- blog3
- 前言
- 關於難度和題目量
- 關於知識點
- 設計與分析
- pta-7
- 一、專案簡介
- 二、專案實現
- 三、專案測試
- 四、程式碼示例
- 五、總結
- 六、程式碼分析
- pta-8
- 一、專案簡介
- 二、專案實現
- 三、專案測試
- 四、程式碼示例
- 五、總結
- 六、程式碼分析
- pta-7
- 改進建議
- 前言
blog3
前言
關於難度和題目量
前三次大作業難度屬於偏難水平,題目量也在可承受範圍內
關於知識點
以下是一些總結的知識點:
- 類的定義:在Java中,使用class關鍵字來定義類,可以包含屬性和方法。
- 繼承和抽象類:透過extends關鍵字實現類的繼承,抽象類使用abstract關鍵字定義,抽象方法需要在子類中實現。
- 介面:介面定義了一組方法的規範,類透過implements關鍵字實現介面,實現介面的類需要實現介面中定義的所有方法。
- HashMap和ArrayList:HashMap是Java中的雜湊表實現,用於儲存鍵值對;ArrayList是動態陣列,用於儲存物件的集合。
- 正規表示式:透過Pattern和Matcher類實現正規表示式的匹配和提取。
- 輸入輸出:使用Scanner類實現從控制檯輸入資料,System.out.println()用於輸出資料。
- 排序:使用Collections.sort()方法對集合進行排序。
- 方法的重寫和過載:在子類中重寫父類的方法,實現不同的功能;方法過載是指在同一個類中,方法名相同但引數列表不同的情況。
- 深度複製: 複製之後的物件有一個新的地址
設計與分析
pta-7
一、專案簡介
本文將介紹如何使用 Java 實現一個簡單的電路系統。該系統可以模擬開關、調速器、風扇、燈泡等電子元件的工作狀態,並根據使用者輸入的指令進行相應的操作。
二、專案實現
- 裝置類:定義了裝置類
Device
,其中包含裝置名稱、是否開啟、引腳 1 電壓、引腳 2 電壓、電阻、電流等屬性,以及顯示裝置資訊、改變裝置狀態、調速等方法。 - 控制裝置類:定義了控制裝置類
ControlledDevice
,繼承自裝置類Device
,其中包含改變裝置狀態的方法。 - 控制裝置類:定義了控制裝置類
ControllingDevice
,繼承自裝置類Device
,其中包含調速方法。 - 串聯電路類:定義了串聯電路類
SeriesCircuit
,繼承自裝置類Device
,其中包含計算電流的方法。 - 開關類:定義了開關類
Switch
,繼承自控制裝置類ControllingDevice
,其中包含開啟和關閉開關的方法。 - 調速器類:定義了調速器類
SpeedController
,繼承自控制裝置類ControllingDevice
,其中包含調速方法。 - 連續調速器類:定義了連續調速器類
ContinuousSpeedController
,繼承自調速器類SpeedController
,其中包含改變調速值的方法。 - 換擋調速器類:定義了換擋調速器類
ShiftSpeedController
,繼承自調速器類SpeedController
,其中包含換擋的方法。 - 風扇類:定義了風扇類
Fan
,繼承自控制裝置類ControlledDevice
,其中包含計算風速的方法。 - 吊扇類:定義了吊扇類
CeilingFan
,繼承自風扇類Fan
,其中包含計算風速的具體實現。 - 燈泡類:定義了燈泡類
Lamp
,繼承自控制裝置類ControlledDevice
,其中包含計算亮度的方法。 - 白熾燈類:定義了白熾燈類
IncandescentLamp
,繼承自燈泡類Lamp
,其中包含計算亮度的具體實現。 - 熒光燈類:定義了熒光燈類
FluorescentLamp
,繼承自燈泡類Lamp
,其中包含計算亮度的具體實現。 - 主函式類:定義了主函式類
Main
,其中包含獲取裝置物件、處理使用者指令、更新裝置狀態、顯示裝置資訊等方法。
三、專案測試
- 輸入裝置指令,例如
[VCC 1-1]
、[1-2 2-1]
、[2-2 GND]
等。 - 輸入控制指令,例如
#K1
、#F1+
、#L1:on
等。 - 輸入結束指令
end
。 - 程式將輸出裝置的狀態資訊,例如開關的開啟或關閉狀態、調速器的當前速度、風扇的風速、燈泡的亮度等。
四、程式碼示例
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ArrayList<String> stringArrayList = new ArrayList<>();
while (true) {
String s = scanner.nextLine();
if (s.equals("end")) {
break;
} else {
stringArrayList.add(s);
}
}
ArrayList<Device> deviceArrayList = new ArrayList<>();
for (String s : stringArrayList) {
if (GetDevice(s)!= null) {
deviceArrayList.add(GetDevice(s));
}
}
deviceArrayList.remove(deviceArrayList.size() - 2);
a(stringArrayList, deviceArrayList);
if (b(deviceArrayList)) {
if (deviceArrayList.size() == 1) {
deviceArrayList.get(0).setPin1(220);
} else {
for (int i = 0; i < deviceArrayList.size() - 1; i++) {
deviceArrayList.get(i).SpeedRegulation();
deviceArrayList.get(i + 1).setPin1(deviceArrayList.get(i).getPin2());
}
}
} else {
for (Device device : deviceArrayList) {
device.setPin1(0);
device.setPin2(0);
}
}
for (Device device : deviceArrayList) {
if (device instanceof Switch) {
device.show();
}
}
for (Device device : deviceArrayList) {
if (!(device instanceof Switch)) {
device.show();
}
}
}
}
五、總結
透過以上步驟,我們可以使用 Java 實現一個簡單的電路系統。該系統可以模擬開關、調速器、風扇、燈泡等電子元件的工作狀態,並根據使用者輸入的指令進行相應的操作。
六、程式碼分析
Metrics Details For File 'pta5.java'
Parameter Value
========= =====
Project Directory C:\Users\11813\Desktop\java檔案
Project Name blog2
Checkpoint Name Baseline
File Name pta5.java
Lines 384*
Statements 274
Percent Branch Statements 21.5
Method Call Statements 95
Percent Lines with Comments 0.0
Classes and Interfaces 14
Methods per Class 3.64
Average Statements per Method 3.71
Line Number of Most Complex Method 362
Name of Most Complex Method Main.main()
Maximum Complexity 16
Line Number of Deepest Block 317
Maximum Block Depth 6
Average Block Depth 2.27
Average Complexity 2.25
Most Complex Methods in 13 Class(es): Complexity, Statements, Max Depth, Calls
CeilingFan.CalculateSpeed() 5, 11, 3, 3
CeilingFan.CeilingFan() 1, 1, 2, 1
CeilingFan.show() 1, 2, 2, 2
ContinuousSpeedController.change() 1, 1, 2, 0
ContinuousSpeedController.ContinuousSpeedController() 1, 1, 2, 1
ContinuousSpeedController.show() 1, 1, 2, 1
ContinuousSpeedController.SpeedRegulation() 1, 1, 2, 1
ControlledDevice.ControlledDevice() 1, 1, 2, 1
ControllingDevice.ControllingDevice() 1, 1, 2, 1
Device.change() 1, 0, 0, 0
Device.Device() 1, 0, 0, 0
Device.getI() 1, 1, 2, 0
Device.getName() 1, 1, 2, 0
Device.getPin1() 1, 1, 2, 0
Device.getPin2() 1, 1, 2, 0
Device.getR() 1, 1, 2, 0
Device.isOpen() 1, 1, 2, 0
Device.setI() 1, 1, 2, 0
Device.setName() 1, 1, 2, 0
Device.setOpen() 1, 1, 2, 0
Device.setPin1() 1, 1, 2, 0
Device.setPin2() 1, 1, 2, 0
Device.setR() 1, 1, 2, 0
Device.show() 1, 0, 0, 0
Device.SpeedRegulation() 1, 0, 0, 0
Fan.Fan() 1, 1, 2, 1
Fan.getSpeed() 1, 1, 2, 0
Fan.setSpeed() 1, 1, 2, 0
FluorescentLamp.CalculateLux() 3, 5, 3, 2
FluorescentLamp.show() 1, 2, 2, 2
IncandescentLamp.CalculateLux() 7, 9, 3, 4
IncandescentLamp.show() 1, 2, 2, 2
Lamp.getLux() 1, 1, 2, 0
Lamp.Lamp() 1, 2, 2, 1
Lamp.setLux() 1, 1, 2, 0
Main.a() 14, 32, 6, 18
Main.b() 3, 4, 4, 1
Main.GetDevice() 13, 38, 5, 21
Main.main() 16, 30, 5, 19
ShiftSpeedController.change() 5, 4, 3, 2
ShiftSpeedController.ShiftSpeedController() 1, 2, 2, 1
ShiftSpeedController.show() 1, 1, 2, 1
ShiftSpeedController.SpeedRegulation() 1, 1, 2, 1
SpeedController.SpeedController() 1, 1, 2, 1
Switch.change() 3, 4, 3, 0
Switch.isOpen() 1, 1, 2, 0
Switch.setOpen() 1, 1, 2, 0
Switch.show() 3, 6, 3, 1
Switch.SpeedRegulation() 3, 4, 3, 2
Switch.Switch() 1, 2, 2, 2
Switch.Switch() 1, 1, 2, 0
Block Depth Statements
0 18
1 67
2 88
3 48
4 32
5 18
6 3
7 0
8 0
9+ 0
pta-8
一、專案簡介
本文將介紹如何使用 Java 實現一個簡單的電路系統。該系統可以模擬開關、調速器、風扇、燈泡等電子元件的工作狀態,並根據使用者輸入的指令進行相應的操作。
二、專案實現
- 裝置類:定義了裝置類
Device
,其中包含裝置名稱、是否開啟、電阻、電流、電壓等屬性,以及計算電阻、計算電流、顯示裝置資訊等方法。 - 控制裝置類:定義了控制裝置類
ControlledDevice
,繼承自裝置類Device
,其中包含改變裝置狀態的方法。 - 控制裝置類:定義了控制裝置類
ControllingDevice
,繼承自裝置類Device
,其中包含調速方法。 - 開關類:定義了開關類
Switch
,繼承自控制裝置類ControllingDevice
,其中包含開啟和關閉開關的方法。 - 調速器類:定義了調速器類
SpeedController
,繼承自控制裝置類ControllingDevice
,其中包含調速方法。 - 連續調速器類:定義了連續調速器類
ContinuousSpeedController
,繼承自調速器類SpeedController
,其中包含改變調速值的方法。 - 換擋調速器類:定義了換擋調速器類
ShiftSpeedController
,繼承自調速器類SpeedController
,其中包含換擋的方法。 - 風扇類:定義了風扇類
Fan
,繼承自控制裝置類ControlledDevice
,其中包含計算風速的方法。 - 吊扇類:定義了吊扇類
CeilingFan
,繼承自風扇類Fan
,其中包含計算風速的具體實現。 - 落地扇類:定義了落地扇類
FloorFan
,繼承自風扇類Fan
,其中包含計算風速的具體實現。 - 燈泡類:定義了燈泡類
Lamp
,繼承自控制裝置類ControlledDevice
,其中包含計算亮度的方法。 - 白熾燈類:定義了白熾燈類
IncandescentLamp
,繼承自燈泡類Lamp
,其中包含計算亮度的具體實現。 - 熒光燈類:定義了熒光燈類
FluorescentLamp
,繼承自燈泡類Lamp
,其中包含計算亮度的具體實現。 - 線路類:定義了線路類
Line
,其中包含裝置列表、是否為主線等屬性,以及計算電阻、計算電流、顯示裝置資訊等方法。 - 並聯電路類:定義了並聯電路類
ParallelCircuits
,其中包含裝置列表等屬性,以及計算電阻、計算電流、顯示裝置資訊等方法。 - 輸入類:定義了輸入類
Input
,其中包含輸入資料、解析資料等方法。 - 主函式類:定義了主函式類
Main
,其中包含讀取輸入資料、解析輸入資料、計算電路狀態、顯示裝置資訊等方法。
三、專案測試
- 輸入裝置指令,例如
#T1:[IN K1]
、#T2:[VCC F1+]
、#M1:T1 T2
等。 - 輸入控制指令,例如
#K1
、#F1+
、#L1:on
等。 - 輸入結束指令
end
。 - 程式將輸出裝置的狀態資訊,例如開關的開啟或關閉狀態、調速器的當前速度、風扇的風速、燈泡的亮度等。
四、程式碼示例
import java.util.ArrayList;
import java.util.Scanner;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
Input input = new Input();
input.getInputData();
TreeMap<String, Device> deviceTreeMap = new TreeMap<>(new ReverseComparator());
ArrayList<Line> list = new ArrayList<>();
input.parse(deviceTreeMap, list);
for (Line line : list) {
if (line.getIsMain() == 1) {
line.countR();
}
}
for (Line line : list) {
if (line.getIsMain() == 1) {
line.setU(220);
int flag = 0;
for (Device device : line.getDeviceArrayList()) {
if (device instanceof SpeedController) {
device.SpeedRegulation();
line.is();
if (line.isOpen()) {
line.setI((220 - device.getU()) / line.getR());
line.countI();
flag = 1;
}
}
}
if (flag == 0) {
line.is();
if (line.isOpen()) {
line.setI(220 / line.getR());
line.countI();
}
}
}
}
for (Device device : deviceTreeMap.values()) {
device.show();
}
}
}
五、總結
透過以上步驟,我們可以使用 Java 實現一個簡單的電路系統。該系統可以模擬開關、調速器、風扇、燈泡等電子元件的工作狀態,並根據使用者輸入的指令進行相應的操作。
六、程式碼分析
Metrics Details For File 'pta6.java'
Parameter Value
========= =====
Project Directory C:\Users\11813\Desktop\java檔案
Project Name blog2
Checkpoint Name Baseline
File Name pta6.java
Lines 746*
Statements 572
Percent Branch Statements 17.0
Method Call Statements 263
Percent Lines with Comments 0.3
Classes and Interfaces 18
Methods per Class 4.72
Average Statements per Method 5.09
Line Number of Most Complex Method 557
Name of Most Complex Method Input.parse()
Maximum Complexity 30
Line Number of Deepest Block 581
Maximum Block Depth 9+
Average Block Depth 2.60
Average Complexity 2.25
Most Complex Methods in 18 Class(es): Complexity, Statements, Max Depth, Calls
CeilingFan.CeilingFan() 1, 1, 2, 1
CeilingFan.Copy() 1, 9, 2, 6
CeilingFan.Count() 5, 11, 3, 3
CeilingFan.show() 1, 2, 2, 2
ContinuousSpeedController.change() 1, 1, 2, 0
ContinuousSpeedController.ContinuousSpeedController() 1, 1, 2, 1
ContinuousSpeedController.Copy() 1, 9, 2, 6
ContinuousSpeedController.getA() 1, 1, 2, 0
ContinuousSpeedController.setA() 1, 1, 2, 0
ContinuousSpeedController.show() 1, 1, 2, 1
ContinuousSpeedController.SpeedRegulation() 1, 1, 2, 1
ControlledDevice.ControlledDevice() 1, 1, 2, 1
ControllingDevice.ControllingDevice() 1, 1, 2, 1
Device.change() 1, 0, 0, 0
Device.Copy() 1, 6, 2, 0
Device.Count() 1, 0, 0, 0
Device.countI() 1, 0, 0, 0
Device.countR() 1, 1, 2, 0
Device.Device() 1, 0, 0, 0
Device.getI() 1, 1, 2, 0
Device.getName() 1, 1, 2, 0
Device.getR() 1, 1, 2, 0
Device.getU() 1, 1, 2, 0
Device.is() 1, 0, 0, 0
Device.isOpen() 1, 1, 2, 0
Device.setI() 1, 1, 2, 0
Device.setName() 1, 1, 2, 0
Device.setOpen() 1, 1, 2, 0
Device.setR() 1, 1, 2, 0
Device.setU() 1, 1, 2, 0
Device.show() 1, 0, 0, 0
Device.SpeedRegulation() 1, 0, 0, 0
Fan.Fan() 1, 1, 2, 1
Fan.getSpeed() 1, 1, 2, 0
Fan.setSpeed() 1, 1, 2, 0
FloorFan.Copy() 1, 9, 2, 6
FloorFan.Count() 11, 17, 3, 6
FloorFan.FloorFan() 1, 1, 2, 1
FloorFan.show() 1, 2, 2, 2
FluorescentLamp.Copy() 1, 9, 2, 6
FluorescentLamp.Count() 3, 5, 3, 2
FluorescentLamp.FluorescentLamp() 1, 1, 2, 1
FluorescentLamp.show() 1, 2, 2, 2
IncandescentLamp.Copy() 1, 9, 2, 6
IncandescentLamp.Count() 7, 9, 3, 4
IncandescentLamp.IncandescentLamp() 1, 1, 2, 1
IncandescentLamp.show() 1, 2, 2, 2
Input.a() 7, 10, 5, 12
Input.deepCopyArrayList() 2, 4, 3, 3
Input.getInputData() 4, 8, 4, 3
Input.parse() 30, 99, 9, 80
Lamp.getLux() 1, 1, 2, 0
Lamp.Lamp() 1, 2, 2, 1
Lamp.setLux() 1, 1, 2, 0
Line.Copy() 1, 10, 2, 7
Line.countI() 3, 9, 3, 7
Line.countR() 3, 9, 3, 4
Line.getDeviceArrayList() 1, 1, 2, 0
Line.getIsMain() 1, 1, 2, 0
Line.is() 3, 6, 4, 4
Line.setDeviceArrayList() 1, 1, 2, 0
Line.setIsMain() 1, 1, 2, 0
Main.b() 3, 4, 4, 1
Main.main() 11, 27, 7, 20
ParallelCircuits.Copy() 1, 9, 2, 6
ParallelCircuits.countI() 4, 14, 4, 8
ParallelCircuits.countR() 7, 17, 5, 6
ParallelCircuits.getDeviceArrayList() 1, 1, 2, 0
ParallelCircuits.is() 3, 6, 4, 4
ParallelCircuits.setDeviceArrayList() 1, 1, 2, 0
ReverseComparator.compare() 9, 23, 4, 6
ShiftSpeedController.change() 5, 4, 3, 2
ShiftSpeedController.Copy() 1, 9, 2, 6
ShiftSpeedController.getArr() 1, 1, 2, 0
ShiftSpeedController.getShift() 1, 1, 2, 0
ShiftSpeedController.setShift() 1, 1, 2, 0
ShiftSpeedController.ShiftSpeedController() 1, 2, 2, 1
ShiftSpeedController.show() 1, 1, 2, 1
ShiftSpeedController.SpeedRegulation() 1, 1, 2, 1
SpeedController.SpeedController() 1, 1, 2, 1
Switch.change() 3, 4, 3, 3
Switch.Copy() 1, 7, 2, 5
Switch.show() 3, 6, 3, 2
Switch.Switch() 1, 2, 2, 2
Switch.Switch() 1, 1, 2, 1
Block Depth Statements
0 21
1 118
2 238
3 59
4 42
5 53
6 22
7 5
8 10
9+ 4
改進建議
- 異常處理:
- 在
input
方法中,當使用者輸入end
時,可能會導致scanner.nextLine
丟擲NoSuchElementException
。可以在try-catch
塊中捕獲該異常,並優雅地處理結束輸入的情況。 - 在解析輸入資料的過程中,如果遇到格式不正確的行,可以丟擲自定義的異常,並在
main
方法中捕獲和處理該異常,而不是直接列印錯誤資訊。
- 在
- 程式碼註釋:
- 在關鍵程式碼段新增註釋,解釋其功能和邏輯。
- 為類和方法新增文件註釋,說明其作用、引數和返回值。
- 使用者介面:
- 提供命令列選項,讓使用者可以指定輸入檔案和輸出檔案的路徑。
- 考慮新增一些簡單的互動提示,例如提示使用者輸入
end
來結束輸入。
- 資料驗證:
- 在解析問題庫和試卷時,檢查題號是否重複。
- 對於答案,檢查其是否符合問題的型別(單選、多選、填空等)。
- 效能最佳化:
- 對於頻繁使用的
HashMap
,可以考慮在建立時指定初始容量,以提高效能。 - 如果需要處理大量資料,可以考慮使用
BufferedReader
來逐行讀取輸入檔案,而不是一次性讀取所有內容到記憶體中。
- 對於頻繁使用的
- 程式碼結構:
- 將不同型別的問題(單選、多選、填空)抽象為不同的類,繼承自一個共同的父類,以提高程式碼的可讀性和可維護性。
- 將解析輸入資料的邏輯提取到單獨的類中,以減少程式碼的複雜度。
- 測試用例:
- 編寫更多的測試用例,覆蓋各種情況,包括邊界情況和異常情況。
- 使用測試框架(如JUnit)來自動化測試過程。
- 日誌記錄:
- 在關鍵位置新增日誌記錄,以便在出現問題時能夠快速定位和解決。
- 可以將日誌輸出到檔案或控制檯。
- 擴充套件性:
- 設計程式碼時考慮到未來可能的擴充套件,例如支援新的問題型別或檔案格式。
- 使用介面或抽象類來定義一些通用的功能,以便在需要時進行擴充套件。
- 程式碼風格:
- 遵循統一的程式碼風格,例如使用空格或製表符進行縮排、命名變數和方法時使用有意義的名稱等。
- 可以使用程式碼格式化工具來自動格式化程式碼,確保風格一致。
以下是一個簡單的示例,展示瞭如何新增異常處理和日誌記錄:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
class QuestionBase {
// 其他程式碼不變
}
abstract class Question {
// 其他程式碼不變
}
class SingleQuestion extends Question {
// 其他程式碼不變
}
class GapFillQuestion extends Question {
// 其他程式碼不變
}
class MulQuestion extends Question {
// 其他程式碼不變
}
class QuestionInPaper {
// 其他程式碼不變
}
class TextPaper {
// 其他程式碼不變
}
class Answer {
// 其他程式碼不變
}
class AnswerPaper implements Comparable<AnswerPaper> {
// 其他程式碼不變
}
class Student {
// 其他程式碼不變
}
class Parse {
// 其他程式碼不變
// 新增方法:處理輸入異常
public static ArrayList<String> input() {
Scanner scanner = new Scanner(System.in);
ArrayList<String> stringArrayList = new ArrayList<>();
try {
while (true) {
String str4 = scanner.nextLine();
if (str4.equals("end")) {
break;
}
stringArrayList.add(str4);
}
} catch (Exception e) {
// 處理異常情況,例如輸入異常
System.out.println("輸入異常,請檢查輸入內容。");
}
return stringArrayList;
}
// 新增方法:記錄日誌
public static void log(String message) {
// 可以將日誌輸出到檔案或控制檯
System.out.println("Log: " + message);
}
}
class Show {
// 其他程式碼不變
}
public class Main {
public static void main(String[] args) {
ArrayList<String> stringArrayList = Parse.input(); // 輸入資料用 list 的方式儲存
HashMap<Integer, Question> questionHashMap = new HashMap<>(); // question.N question
Parse parse = new Parse();
questionHashMap = parse.Toquestionhashmap(stringArrayList);
questionHashMap = parse.DeleteQuestion(questionHashMap, stringArrayList);
HashMap<Integer, TextPaper> textPaperHashMap = parse.ToHashPaper(stringArrayList, questionHashMap);
HashMap<String, Student> stringStudentHashMap = parse.ToStudentHashmap(stringArrayList);
ArrayList<AnswerPaper> answerPaperArrayList = parse.ToAnswerpaperArraylist(stringArrayList, textPaperHashMap);
ArrayList<TextPaper> textPaperArrayList = parse.TotextPaperArrayList(stringArrayList, questionHashMap);
Show show = new Show();
show.ShowWrongFormat(stringArrayList);
show.ShowTextPaperScore(textPaperArrayList);
Collections.sort(answerPaperArrayList);
for (AnswerPaper answerPaper : answerPaperArrayList) {
answerPaper = show.show1(answerPaper);
show.show2(answerPaper, stringStudentHashMap);
}
}
}
在上述示例中,我們新增了一個input
方法來處理輸入異常,並使用log
方法記錄日誌。這樣可以提高程式碼的健壯性和可維護性。