一、前言
PTA作業已經進入第二階段,第二階段與第一階段的題目有所不同,主要為電路模擬程式
這三次的PTA作業第一次為“答題判題程式-4” ,他是以前三次答題判題程式為基礎所擴充套件的;第二次作業為全新的題型“家居強電電路模擬程式-1”,主要內容為設計一個智慧家居強電電路模擬系統;第三次作業是以“家居強電電路模擬程式-1”為基礎迭代的“家居強電電路模擬程式-2”,它在1的基礎上增加了並聯電路,修改了輸入格式等等。雖然難度上總體小於答題判題程式,但還是有挑戰性的。
二、設計與分析
接下來,我將會對這三次的作業進行分析。
點選檢視程式碼
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
}
}
abstract class DealStr {
protected String line;
public DealStr() {
}
public DealStr(String line) {
this.line = line;
}
}
class StrWithN extends DealStr{
public StrWithN() {
super();
}
public N_Question dealStr() {
N_Question question = new N_Question();
//QuestionPaper qusetionpaper = new QuestionPaper();
String[] input = line.split("#N:| #Q:| #A:");
String num = input[1].trim();
String content = input[2].trim();
String answer = input[3].trim();
question.setNum(num);
question.setContent(content);
question.setAnswer(answer);
//qusetionpaper.setQuestion_n(num, question);
return question;
}
}
class StrWithK extends DealStr {
}
class StrWithZ extends DealStr {
}
class StrWithX extends DealStr {
}
class StrWithT extends DealStr {
}
class StrWithS extends DealStr {
}
class QuestionPaper {
HashMap<String, N_Question> question_n = new HashMap();
HashMap<String, K_Question> question_k = new HashMap();
HashMap<String, Z_Question> question_z = new HashMap();
public HashMap<String, N_Question> getQuestion_n() {
return question_n;
}
/*public void setQuestion_n(HashMap<String, N_Question> question_n) {
this.question_n = question_n;
}*/
public void setQuestion_n(String num, N_Question question_n) {
this.question_n.put(num, question_n);
}
public HashMap<String, K_Question> getQuestion_k() {
return question_k;
}
/*public void setQuestion_k(HashMap<String, K_Question> question_k) {
this.question_k = question_k;
}*/
public void setQuestion_k(String num, K_Question question_k) {
this.question_k.put(num, question_k);
}
public HashMap<String, Z_Question> getQuestion_z() {
return question_z;
}
/*public void setQuestion_z(HashMap<String, Z_Question> question_z) {
this.question_z = question_z;
}*/
public void setQuestion_z(String num, Z_Question question_z) {
this.question_z.put(num, question_z);
}
}
abstract class Question {
protected String num;
protected String content;
//protected String answer;
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
class N_Question extends Question {
protected String answer;
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
}
class Z_Question extends Question {
protected String[] answer;
public String[] getAnswer() {
return answer;
}
public void setAnswer(String[] answer) {
this.answer = answer;
}
}
class K_Question extends Question {
protected String[] answer;
public String[] getAnswer() {
return answer;
}
public void setAnswer(String[] answer) {
this.answer = answer;
}
}
class TextPaper {
}
class AnswerSheet {
}
class StudentInfo {
}
class DeleteQuestion {
}
1、答題判題程式-4
以下是程式碼的類圖
“答題判題程式-4”在“答題判題程式-3”的基礎上新增內容為輸入選擇題題目資訊、輸入填空題題目資訊、輸出順序變化以及多張試卷資訊
這次的程式碼我並未寫出來,沒能得分,只設計了類結構圖,上述程式碼也是不完整的程式碼,因為能力有限,再加上其他科目的作業需求,導致沒能完成程式碼。
因為前三次我的程式碼並沒有可擴充套件性和可維護性,所以我重新設計了類結構圖。我將字串處理類DealStr抽象,並定義了多個子類繼承字串處理類DealStr來處理不同的輸入,為的是應對下次迭代時需要增加或修改輸入方式。同樣,我將問題類Question也抽象化,並定義多個子類繼承Question類,每個子類都是不同的題型,同樣是為了在下次迭代時增加題型做準備。
QuestionPaper類時是試卷類,用來儲存試卷的題目,QuestionPaper類中有三種HashMa屬性來儲存不同的題型,TextPaper類則是用來儲存多張答卷;AnswerSheet類則是儲存試卷答案,其中也有HashMap屬性用來儲存答案,利用鍵值對來與試卷進行繫結。
上述類圖還不是很完整,還需定義輸出類來對試卷及學生資訊進行輸出。
總的來說,這一次的作業我並沒有花多少心思去完成,更多的是抱著僥倖(那麼多人沒做那我也不做)
回顧前三次”答題判題程式“作業,我深刻認識到自己在程式設計能力和問題解決能力上的不足。首先,我在“答題判題程式-4”的實現上缺乏耐心和毅力,導致程式碼未能完成,這是我對自身責任感和執行力的一次深刻反思。其次,我在程式碼設計和實現上缺乏經驗,沒有充分考慮到可擴充套件性和可維護性,這使得我在面對新的題型和需求時顯得力不從心。
2、家居強電電路模擬程式-1
點選檢視程式碼
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
SeriesCircuit circuit = new SeriesCircuit();
Operation operations = new Operation();
InputProcessing input = null;
String line = scanner.nextLine();
while (true) {
if (!line.startsWith("[")) {
break;
}
input = new InputProcessing(line);
if (JudgeEquipment.judge(input.equipmentName) != null)
circuit.addEquipment(JudgeEquipment.judge(input.equipmentName));
line = scanner.nextLine();
}
while (true) {
if (line.equals("end") || !line.startsWith("#")) {
break;
}
input = new InputProcessing(line);
operations.addOperation(input.operation);
line = scanner.nextLine();
}
OperationsProcessing operationsPro = new OperationsProcessing(circuit, operations);
operationsPro.operationsProcessing();
View view = new View(operationsPro.getEquipments());
view.view();
}
}
class OperationsProcessing {
SeriesCircuit circuit = new SeriesCircuit();
Operation operations = new Operation();
List<ElectricEquipment> equipments = new ArrayList<>();
int F = 0;
int L = 0;
public OperationsProcessing(SeriesCircuit circuit, Operation operations) {
this.circuit = circuit;
this.operations = operations;
}
public void operationsProcessing() {
for (ElectricEquipment equipment : circuit.getEquipments()) {
int flag = 0;
for (String operation : operations.getOperation()) {
if (operation.startsWith("K")) {
if (operation.equals(equipment.name)) {
((Switch) equipment).setState();
if (((Switch) equipment).count <= 1) {
equipments.add(equipment);
flag = 1;
}
}
} else if (operation.startsWith("F")) {
F ++;
if (operation.charAt(2) == '+') {
operation = operation.substring(0, operation.length() - 1);
if (operation.equals(equipment.name)) {
((SplitGovernor) equipment).upGear();
if (F <= 1) {
equipments.add(equipment);
flag = 1;
}
}
} else if (operation.charAt(2) == '-') {
operation = operation.substring(0, operation.length() - 1);
if (operation.equals(equipment.name)) {
((SplitGovernor) equipment).downGear();
if (F <= 1) {
equipments.add(equipment);
flag = 1;
}
}
}
} else if (operation.startsWith("L")) {
L ++;
String[] operation1 = operation.split(":");
if (operation1[0].equals(equipment.name)) {
((ContinueGovernor) equipment).setPosition(Double.parseDouble(operation1[1]));
if (L <= 1) {
equipments.add(equipment);
flag = 1;
break;
}
}
}
}
if (flag == 0) {
equipments.add(equipment);
}
}
}
public List<ElectricEquipment> getEquipments() {
return this.equipments;
}
}
class View {
private List<ElectricEquipment> equipments = new ArrayList<>();
private double voltage;
public View(List<ElectricEquipment> equipments) {
this.equipments = equipments;
this.voltage = 220.0;
}
public void view() {
int switchCount = 0;
for (ElectricEquipment equipment : equipments) {
if (equipment.name.startsWith("K")) {
switchCount ++;
}
}
int closedCount = 0;
for (ElectricEquipment equipment : equipments) {
if (equipment.name.startsWith("K")) {
if (((Switch) equipment).getState() == 1) {
closedCount ++;
}
}
}
for (ElectricEquipment equipment : equipments) {
if (equipment.name.startsWith("K")) {
((Switch) equipment).show();
}
}
for (ElectricEquipment equipment1 : equipments) {
if (equipment1.name.startsWith("F")) {
if (switchCount == closedCount)
this.voltage = ((SplitGovernor) equipment1).getOutputVoltage(this.voltage);
((SplitGovernor) equipment1).show();
}
}
for (ElectricEquipment equipment2 : equipments) {
if (equipment2.name.startsWith("L")) {
if (switchCount == closedCount)
this.voltage = ((ContinueGovernor) equipment2).getOutputVoltage(this.voltage);
((ContinueGovernor) equipment2).show();
}
}
for (ElectricEquipment equipment3 : equipments) {
if (equipment3.name.startsWith("B")) {
if (switchCount == closedCount)
((IncandescentLight) equipment3).setVoltage(voltage);
((IncandescentLight) equipment3).show();
}
}
for (ElectricEquipment equipment4 : equipments) {
if (equipment4.name.startsWith("R")) {
if (switchCount == closedCount)
((DaylightLamp) equipment4).setVoltage(voltage);
((DaylightLamp) equipment4).show();
}
}
for (ElectricEquipment equipment : equipments) {
if (equipment.name.startsWith("D")) {
if (switchCount == closedCount)
((CeilingFan) equipment).setVoltage(voltage);
((CeilingFan) equipment).show();
}
}
}
}
class Operation {
List<String> operations = new ArrayList<>();
public Operation() {
}
public List<String> getOperation() {
return this.operations;
}
public void addOperation(String operation) {
operations.add(operation);
}
}
class InputProcessing {
protected String equipmentName;
protected String operation;
public InputProcessing(String str) {
if (str.startsWith("[")) {
String[] str11 = str.split("\\[| |\\]");
this.equipmentName = str11[1];
} else if (str.startsWith("#")) {
String[] str22 = str.split("#");
this.operation = str22[1];
}
}
}
class JudgeEquipment {
public JudgeEquipment() {
}
public static ElectricEquipment judge(String str) {
if (str.startsWith("K")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new Switch();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("F")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new SplitGovernor();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("L")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new ContinueGovernor();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("B")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new IncandescentLight();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("R")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new DaylightLamp();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("D")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new CeilingFan();
equipment.name = str1[0];
return equipment;
} else
return null;
}
}
abstract class ElectricEquipment {
protected String name;
protected double pin1;
protected double pin2;
protected double voltage = 0.0;
}
class SeriesCircuit { //串聯電路
List<ElectricEquipment> equipments = new ArrayList<>();
public SeriesCircuit() {
}
public void addEquipment(ElectricEquipment equipment) {
equipments.add(equipment);
}
public List<ElectricEquipment> getEquipments() {
return equipments;
}
public void view1() {
for (ElectricEquipment equipment : equipments) {
System.out.println(equipment.name);
}
}
}
class CeilingFan extends ElectricEquipment {//D
private double speed = 0;
private int statu = 0;
public void setVoltage(double voltage) {
this.voltage = voltage;
}
public double getSpeed() {
if (voltage < 80) {
return 0;
} else if (voltage <= 150) {
return voltage * 4.0 - 240;
} else {
return 360;
}
}
public void show() {
System.out.println("@" + name + ":" + (int) Math.floor(getSpeed()));
}
}
class IncandescentLight extends ElectricEquipment {//B
private int brightness;
private int statu = 0;
public void setVoltage(double voltage) {
this.voltage = voltage;
}
public double getBrightness() {
if (voltage <= 9) {
return 0;
} else if (voltage <= 10) {
return voltage * 50.0 - 450;
} else if (voltage <= 220) {
return voltage * (5 / 7.0) + (300 / 7.0);
} else {
return 200;
}
}
public void show() {
System.out.println("@" + name + ":" + (int) Math.floor(getBrightness()));
}
}
class DaylightLamp extends ElectricEquipment {//R
private double brightness = 180;
public void setVoltage(double voltage) {
this.voltage = voltage;
}
public double getBrightness() {
if (voltage != 0) {
return brightness;
} else {
return 0;
}
}
public void show() {
System.out.println("@" + name + ":" + (int) Math.floor(getBrightness()));
}
}
class ContinueGovernor extends ElectricEquipment {//L
private double position = 0.00;
public void setPosition(double position) {
if (position >= 0.0 && position <= 1.0) {
this.position = position;
}
}
public double getPosition() {
return this.position;
}
public double getOutputVoltage(double inputVoltage) {
return getPosition() * inputVoltage;
}
public void show() {
System.out.println("@" + name + ":" + String.format("%.2f", position));
}
}
class SplitGovernor extends ElectricEquipment {//F
private int gear = 0;
public void upGear() {
if (gear < 3)
this.gear ++;
}
public void downGear() {
if (gear > 0)
this.gear --;
}
public double getOutputVoltage(double inputVoltage ) {
switch (gear) {
case 0:
return 0;
case 1:
return inputVoltage * 0.3;
case 2:
return inputVoltage * 0.6;
case 3:
return inputVoltage * 0.9;
default:
return 0;
}
}
public void show() {
System.out.println("@" + name + ":" + gear);
}
}
class Switch extends ElectricEquipment{
protected int count = 1;
private int state = 0;
public void open() {
this.state = 1;
}
public void close() {
this.state = 0;
}
public void setState() {
this.count ++;
if (this.count % 2 == 0) {
this.state = 1;
} else
this.state = 0;
}
public int getState() {
return state;
}
public void show() {
if (state == 1)
System.out.println("@" + name + ":closed");
else
System.out.println("@" + name + ":turned on");
}
}
以下是程式碼的類圖
這次為新的題目”家居強電電路模擬程式-1“,吸取答題判題程式的教訓,我設計了很多類用來實現單一職責原則,雖然並不是很好,但比答題判題程式好
透過類圖可以知道,我定義了一個抽象電路裝置類ElectricEquipment類,這個類是所有電器裝置的基類,提供了一些通用的屬性和方法。屬性包括裝置名稱(name)、兩個埠的電壓(pin1和pin2)、當前電壓(voltage)。方法包括設定電壓(setVoltage)和顯示裝置資訊(show)。後面我將介紹主要的幾個類。
SeriesCircuit(串聯電路類):
這個類用於模擬一個串聯電路,包含一個電器裝置列表。方法包括新增裝置(addEquipment)和顯示電路中的裝置(view1)。
ContinueGovernor(連續調速器類):
這個類是ElectricEquipment的子類,用於模擬連續調速器的功能。
屬性包括當前位置(position)。
方法包括設定位置(setPosition)、獲取輸出電壓(getOutputVoltage)和顯示調速器資訊(show)。
SplitGovernor(調壓器類):
這個類也是ElectricEquipment的子類,用於模擬分檔調速器的功能。
屬性包括當前檔位(gear)。
方法包括升檔(upGear)、降檔(downGear)、獲取輸出電壓(getOutputVoltage)和顯示調速器資訊(show)。
JudgeEquipment(裝置判斷類):
這個類用於判斷輸入的裝置名稱,返回對應的電器裝置例項。
Operation(操作類):
這個類用於管理使用者輸入的操作指令,包括新增操作(addOperation)和獲取操作列表(getOperation)。
InputProcessing(輸入處理類):
這個類用於處理使用者的輸入,包括裝置資訊和操作資訊。
View(檢視類):
這個類用於顯示電路的當前狀態,包括各個裝置的資訊和電壓值。
整體來看,透過定義不同的類來模擬家居電路中的各種裝置,每個類都實現了自己的功能,並透過繼承和組合的方式來實現相互之間的協作。可以透過輸入裝置資訊和操作指令來與這個類比電路互動,檢視和控制家中的電器裝置。
在這次作業中有一點尤須注意,電路中會存在多個開關問題,所以我使用了以下程式碼來判斷開關個數以及閉合開關個數來判斷電路是否通路
點選檢視程式碼
int switchCount = 0;
for (ElectricEquipment equipment : equipments) {
if (equipment.name.startsWith("K")) {
switchCount ++;
}
}
int closedCount = 0;
for (ElectricEquipment equipment : equipments) {
if (equipment.name.startsWith("K")) {
if (((Switch) equipment).getState() == 1) {
closedCount ++;
}
}
}
還有輸出順序,輸出順序是按照一定的裝置順序輸出,並不是按照電路中裝置順序輸出,因此我使用了多個增強for迴圈以及if語句來判斷輸出,程式碼如下
點選檢視程式碼
for (ElectricEquipment equipment : equipments) {
if (equipment.name.startsWith("K")) {
((Switch) equipment).show();
}
}
for (ElectricEquipment equipment1 : equipments) {
if (equipment1.name.startsWith("F")) {
if (switchCount == closedCount)
this.voltage = ((SplitGovernor) equipment1).getOutputVoltage(this.voltage);
((SplitGovernor) equipment1).show();
}
}
for (ElectricEquipment equipment2 : equipments) {
if (equipment2.name.startsWith("L")) {
if (switchCount == closedCount)
this.voltage = ((ContinueGovernor) equipment2).getOutputVoltage(this.voltage);
((ContinueGovernor) equipment2).show();
}
}
for (ElectricEquipment equipment3 : equipments) {
if (equipment3.name.startsWith("B")) {
if (switchCount == closedCount)
((IncandescentLight) equipment3).setVoltage(voltage);
((IncandescentLight) equipment3).show();
}
}
for (ElectricEquipment equipment4 : equipments) {
if (equipment4.name.startsWith("R")) {
if (switchCount == closedCount)
((DaylightLamp) equipment4).setVoltage(voltage);
((DaylightLamp) equipment4).show();
}
}
for (ElectricEquipment equipment : equipments) {
if (equipment.name.startsWith("D")) {
if (switchCount == closedCount)
((CeilingFan) equipment).setVoltage(voltage);
((CeilingFan) equipment).show();
}
}
整體來看,這個程式比之前的答題判題程式有了明顯改進,但是還是不夠好,對類結構設計也還只是學到了皮毛,並不能真正滿足需求,但每次都進步一點,就會越來越好!
3、家居強電電路模擬程式-2
點選檢視程式碼
package pta6;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Collections;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
SeriesCircuit seriesCircuit = new SeriesCircuit(); //存equipments
Operation operations = new Operation();
InputProcessing input = null;
InputCircuitProcessing input1 = null;
ParallelCircuitProcessing parallelCircuitProcessing;
String line = scanner.nextLine();
List<ElectricEquipment> allCircuit = new ArrayList<>(); //所有輸入的並聯支路T,存T
List<ElectricEquipment> allParallels = new ArrayList<>(); //所有的並聯支路M
while (true) {
if (!line.startsWith("#T"))
break;
input1 = new InputCircuitProcessing(line);
List<String> circuitEquipment = SplitCircuitEquipment.splitCircuit(input1.parallelCircuit);
parallelCircuitProcessing = new ParallelCircuitProcessing();
allCircuit.add(parallelCircuitProcessing.getSeriesEquipment(circuitEquipment, input1.circuitName));
line = scanner.nextLine();
}
while (true) {
if (!line.startsWith("#M"))
break;
ParallelCircuit parallelCircuits = new ParallelCircuit(); //電路中的並聯支路M,存T
SplitSeriesCircuit splitSeriesCircuit = new SplitSeriesCircuit();
input1 = new InputCircuitProcessing(line);
String[] circuits = splitSeriesCircuit.splitCircuit(input1.parallelCircuit);
parallelCircuits.name = input1.circuitName;
for (String name : circuits) {
for (ElectricEquipment circuit : allCircuit) {
if (name.equals(circuit.name)) {
parallelCircuits.getCircuits().add(circuit);
}
}
}
allParallels.add(parallelCircuits);
line = scanner.nextLine();
}
while (true) {
if (!line.startsWith("#T"))
break;
input1 = new InputCircuitProcessing(line);
JudgeEquipment judgeEquipment = new JudgeEquipment(allCircuit, allParallels);
List<String> inputEquipments = SplitCircuitEquipment.splitCircuit(input1.parallelCircuit);
for (String inputEquipment : inputEquipments) {
input = new InputProcessing(inputEquipment);
if (judgeEquipment.judge(input.equipmentName) != null)
seriesCircuit.addEquipment(judgeEquipment.judge(input.equipmentName));
}
line = scanner.nextLine();
}
while (true) { //用來進行#K1等操作的輸入
if (line.equals("end") || !line.startsWith("#")) {
break;
}
input = new InputProcessing(line);
operations.addOperation(input.operation);
line = scanner.nextLine();
}
OperationsProcession_1 operationsPro = new OperationsProcession_1();
seriesCircuit = operationsPro.operationsProcessing(seriesCircuit, operations);
Calculation calculation = new Calculation(seriesCircuit);
seriesCircuit = calculation.ResistanceCalculation(seriesCircuit);
seriesCircuit = calculation.calculation(seriesCircuit);
//View.view(seriesCircuit);
for (ElectricEquipment equipment : seriesCircuit.getEquipments()) {
System.out.println(equipment.name);
}
}
}
class Calculation {
SeriesCircuit seriesCircuit = new SeriesCircuit();
Calculate calculate = new Calculate();
public Calculation(SeriesCircuit seriesCircuit) {
this.seriesCircuit = seriesCircuit;
}
public SeriesCircuit ResistanceCalculation(SeriesCircuit seriesCircuit) {
seriesCircuit = (SeriesCircuit) calculate.calculateResistance(seriesCircuit);
return seriesCircuit;
}
public SeriesCircuit calculation(SeriesCircuit seriesCircuit) {
SeriesCircuit newSeriesCircuit = new SeriesCircuit();
double voltage = 220.0;
int switchCount = 0; //開關個數
for (ElectricEquipment equipment : seriesCircuit.getEquipments()) {
if (equipment.name.startsWith("K")) {
switchCount ++;
}
}
int closedCount = 0; //閉合狀態的開關個數
for (ElectricEquipment equipment : seriesCircuit.getEquipments()) {
if (equipment.name.startsWith("K")) {
if (((Switch) equipment).getState() == 1) {
closedCount ++;
}
}
}
for (ElectricEquipment equipment : seriesCircuit.getEquipments()) {
if (equipment.name.startsWith("M")) {
for (ElectricEquipment equipment1 : ((ParallelCircuit) equipment).getCircuits()) {
equipment1 = calculation((SeriesCircuit) equipment1);
for (ElectricEquipment equipment2 : ((SeriesCircuit) equipment1).getEquipments()) {
newSeriesCircuit.addEquipment(equipment2);
}
}
} else if (equipment.name.startsWith("T")) {
equipment = calculation((SeriesCircuit) equipment);
for (ElectricEquipment equipment2 : ((SeriesCircuit) equipment).getEquipments()) {
newSeriesCircuit.addEquipment(equipment2);
}
} else {
if (switchCount == closedCount) {
equipment = calculate.calculate(equipment, voltage, seriesCircuit.resistance);
newSeriesCircuit.addEquipment(equipment);
}
}
}
return newSeriesCircuit;
}
}
class Calculate {
public ElectricEquipment calculate(ElectricEquipment equipment, double v, double r) {
if (equipment.name.startsWith("F")) {
v = ((SplitGovernor) equipment).getOutputVoltage(v);
} else if (equipment.name.startsWith("L")) {
v = ((ContinueGovernor) equipment).getOutputVoltage(v);
} else if (equipment.name.startsWith("B")) {
v = v * (equipment.resistance / (r * 1.0));
((IncandescentLight) equipment).setVoltage(v);
} else if (equipment.name.startsWith("R")) {
v = v * (equipment.resistance / (r * 1.0));
((DaylightLamp) equipment).setVoltage(v);
} else if (equipment.name.startsWith("D")) {
v = v * (equipment.resistance / (r * 1.0));
((CeilingFan) equipment).setVoltage(v);
} else if (equipment.name.startsWith("A")) {
v = v * (equipment.resistance / (r * 1.0)); //equipment.resistance //calculateResistance(equipment).resistance
((FloorFan) equipment).setVoltage(v);
}
return equipment;
}
public ElectricEquipment calculateResistance(ElectricEquipment T) {
double resistance = 0;
Calculate calculate = new Calculate();
for (ElectricEquipment equipment : ((SeriesCircuit) T).getEquipments()) {
double resistance_d = 0;
if (equipment.name.startsWith("M")) {
for (ElectricEquipment equipment1 : ((ParallelCircuit) equipment).getCircuits()) {
equipment1 = calculate.calculateResistance(equipment1);
resistance_d += 1.0 / equipment1.resistance;
}
resistance += 1.0 / resistance_d;
} else if (equipment.name.startsWith("T")) {
equipment = calculate.calculateResistance(equipment);
resistance += equipment.resistance;
} else {
resistance += equipment.resistance;
}
}
T.resistance = resistance;
return T;
}
}
class OperationsProcession_1 {
private double voltage = 220.0;
SeriesCircuit seriesCircuit = new SeriesCircuit();
public SeriesCircuit operationsProcessing(SeriesCircuit circuit, Operation operations) {
for (ElectricEquipment equipment : circuit.getEquipments()) {
if (equipment.name.startsWith("T")) {
SeriesCircuit circuit1 = new SeriesCircuit();
for (ElectricEquipment equipment1 : ((SeriesCircuit) equipment).getEquipments()) {
operate(equipment1, operations);
circuit1.addEquipment(equipment1);
}
seriesCircuit.addEquipment(circuit1);
} else if (equipment.name.startsWith("M")) {
ParallelCircuit circuis = new ParallelCircuit();
for (ElectricEquipment circuit1 : ((ParallelCircuit) equipment).getCircuits()) {
SeriesCircuit circuit2 = new SeriesCircuit();
for (ElectricEquipment equipment1 : ((SeriesCircuit) circuit1).getEquipments()) {
operate(equipment1, operations);
circuit2.addEquipment(equipment1);
}
circuit2.name = circuit1.name;
circuis.addCircuit(circuit2);
}
circuis.name = equipment.name;
seriesCircuit.addEquipment(circuis);
} else {
operate(equipment, operations);
seriesCircuit.addEquipment(equipment);
}
}
return seriesCircuit;
}
public void operate(ElectricEquipment equipment, Operation operations) {
for (String operation : operations.getOperation()) {
if (operation.startsWith("K")) {
if (operation.equals(equipment.name))
((Switch) equipment).setState();
} else if (operation.startsWith("F")) {
if (operation.charAt(2) == '+') {
operation = operation.substring(0, operation.length() - 1);
if (operation.equals(equipment.name))
((SplitGovernor) equipment).upGear();
} else if (operation.charAt(2) == '-') {
operation = operation.substring(0, operation.length() - 1);
if (operation.equals(equipment.name))
((SplitGovernor) equipment).downGear();
}
} else if (operation.startsWith("L")) {
String[] operation1 = operation.split(":");
if (operation1[0].equals(equipment.name))
((ContinueGovernor) equipment).setPosition(Double.parseDouble(operation1[1]));
}
}
}
}
class View { //列印出資料
public static void view(SeriesCircuit equipments) { //列印資料
for (ElectricEquipment equipment : equipments.getEquipments()) {
if (equipment.name.startsWith("K")) {
((Switch) equipment).show();
}
}
for (ElectricEquipment equipment1 : equipments.getEquipments()) {
if (equipment1.name.startsWith("F")) {
((SplitGovernor) equipment1).show();
}
}
for (ElectricEquipment equipment2 : equipments.getEquipments()) {
if (equipment2.name.startsWith("L")) {
((ContinueGovernor) equipment2).show();
}
}
for (ElectricEquipment equipment3 : equipments.getEquipments()) {
if (equipment3.name.startsWith("B")) {
((IncandescentLight) equipment3).show();
}
}
for (ElectricEquipment equipment4 : equipments.getEquipments()) {
if (equipment4.name.startsWith("R")) {
((DaylightLamp) equipment4).show();
}
}
List<ElectricEquipment> equipments5 = new ArrayList<>();
for (ElectricEquipment equipment : equipments.getEquipments()) {
if (equipment.name.startsWith("D")) {
equipments5.add(equipment);
//((CeilingFan) equipment).show();
}
}
Collections.sort(equipments5, new Comparator<ElectricEquipment>() {
@Override
public int compare(ElectricEquipment e1, ElectricEquipment e2) {
return e1.name.compareTo(e2.name);
}
});
for (ElectricEquipment equipment : equipments5) {
((CeilingFan) equipment).show();
}
for (ElectricEquipment equipment : equipments.getEquipments()) {
if (equipment.name.startsWith("A")) {
((FloorFan) equipment).show();
}
}
}
}
class Operation { //儲存輸入的操作的類,比如#K,#F++,#L:0.68
List<String> operations = new ArrayList<>();
public Operation() {
}
public List<String> getOperation() {
return this.operations;
}
public void addOperation(String operation) {
operations.add(operation);
}
}
class InputCircuitProcessing { //處理並聯電路
protected String circuitName;
protected String parallelCircuit;
public InputCircuitProcessing(String str) {
String[] str1 = str.split("#");
String[] str2 = str1[1].split(":");
this.circuitName = str2[0];
this.parallelCircuit = str2[1];
}
}
class InputProcessing { //處理輸入的字串
protected String equipmentName;
protected String operation;
public InputProcessing(String str) {
if (str.startsWith("[")) {
String[] str11 = str.split("\\[| |\\]");
this.equipmentName = str11[1];
} else if (str.startsWith("#")) {
String[] str22 = str.split("#");
this.operation = str22[1];
}
}
}
class SplitCircuitEquipment {
public static List<String> splitCircuit(String str) {
//String[] circuitEquipment = str.split(" ");
// 編譯正規表示式,匹配方括號內的內容
Pattern pattern = Pattern.compile("\\[(.*?)\\]");
Matcher matcher = pattern.matcher(str);
// 使用ArrayList來儲存分割後的字串
List<String> circuitEquipment = new ArrayList<>();
// 迴圈查詢所有匹配項,並儲存到ArrayList中
while (matcher.find()) {
circuitEquipment.add(matcher.group());
}
return circuitEquipment;
}
}
class SplitSeriesCircuit { //分離輸入#M中的電路各個T
public String[] splitCircuit(String circuits) {
String[] circuit = circuits.split("\\[| |\\]");
String[] newCiecuits = new String[circuit.length - 1];
System.arraycopy(circuit, 1, newCiecuits, 0, circuit.length - 1);
return newCiecuits;
}
}
class ParallelCircuitProcessing {
SeriesCircuit seriesEquipments = new SeriesCircuit();
InputProcessing input = null;
public SeriesCircuit getSeriesEquipment(List<String> circuitEquipment, String name) {
JudgeEquipment judgeEquipment1 = new JudgeEquipment();
seriesEquipments.name = name;
for (String line : circuitEquipment) {
input = new InputProcessing(line);
if (judgeEquipment1.judge(input.equipmentName) != null)
seriesEquipments.addEquipment(judgeEquipment1.judge(input.equipmentName));
}
return seriesEquipments;
}
}
class JudgeEquipment {
List<ElectricEquipment> allCircuit;
List<ElectricEquipment> allParallel;
public JudgeEquipment(List<ElectricEquipment> allCircuit, List<ElectricEquipment> allParallel) {
this.allCircuit = allCircuit;
this.allParallel = allParallel;
}
public JudgeEquipment() {
}
public ElectricEquipment judge(String str) {
if (str.startsWith("K")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new Switch();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("F")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new SplitGovernor();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("L")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new ContinueGovernor();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("B")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new IncandescentLight();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("R")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new DaylightLamp();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("D")) {
String[] str1 = str.split("-");
ElectricEquipment equipment = new CeilingFan();
equipment.name = str1[0];
return equipment;
} else if (str.startsWith("M")) {
String[] str1 = str.split("-");
return judgeCircuitM(str1[0]);
} else
return null;
}
public ElectricEquipment judgeCircuitM(String circuitName) {
for (ElectricEquipment Parallel : allParallel) {
if (circuitName.equals(Parallel.name)) {
return Parallel;
}
}
return null;
}
}
abstract class ElectricEquipment { //所有電路裝置的父類,屬於抽象類
protected String name;
protected double pin1;
protected double pin2;
protected double voltage = 0.0;
protected double resistance;
}
abstract class ControlEquipment extends ElectricEquipment {
}
abstract class ControlledEquipment extends ElectricEquipment {
}
class AllParallelCircuit extends ElectricEquipment { //並聯電路集合M
List<ElectricEquipment> parallelCircuits = new ArrayList<>();
public void addparallelCircuit(ParallelCircuit parallelCircuit) {
parallelCircuits.add(parallelCircuit);
}
public List<ElectricEquipment> getParallelCircuits() {
return parallelCircuits;
}
}
class ParallelCircuit extends ElectricEquipment { //並聯電路
protected int state = 0;
List<ElectricEquipment> circuits = new ArrayList<>(); //存SeriesCircuit串聯電路
public void addCircuit(SeriesCircuit circuit) {
circuits.add(circuit);
}
public List<ElectricEquipment> getCircuits() {
return circuits;
}
}
class SeriesCircuit extends ElectricEquipment { //串聯電路,用來儲存電路中的各個裝置
protected int state = 0;
List<ElectricEquipment> equipments = new ArrayList<>(); //存裝置
public void addEquipment(ElectricEquipment equipment) {
equipments.add(equipment);
}
public List<ElectricEquipment> getEquipments() {
return equipments;
}
}
class CeilingFan extends ControlledEquipment {//吊扇類
private double speed = 0;
private int statu = 0;
public CeilingFan() {
resistance = 20;
}
public Double getSpeed() {
return speed;
}
public void setVoltage(double voltage) {
this.voltage = voltage;
}
public void setSpeed() {
if (voltage < 80) {
this.speed = 0;
} else if (voltage <= 150) {
this.speed = voltage * 4.0 - 240;
} else {
this.speed = 360;
}
}
public void show() {
System.out.println("@" + name + ":" + (int) Math.floor(getSpeed()));
}
}
class FloorFan extends ControlledEquipment { //落地扇類 A
private double speed = 0;
private int statu = 0;
public FloorFan() {
resistance = 20;
}
public void setVoltage(double voltage) {
this.voltage = voltage;
}
public double getSpeed() {
return speed;
}
public void setSpeed() {
if (voltage >= 80 && voltage < 100) {
this.speed = 80;
} else if (voltage >= 100 && voltage < 120) {
this.speed = 160;
} else if (voltage >= 120 && voltage < 140) {
this.speed = 260;
} else if (voltage >= 140) {
this.speed = 360;
} else
this.speed = 0;
}
public void show() {
System.out.println("@" + name + ":" + (int) Math.floor(getSpeed()));
}
}
class IncandescentLight extends ControlledEquipment {//白熾燈類
private double brightness;
private int statu = 0;
public IncandescentLight() {
resistance = 10;
}
public void setVoltage(double voltage) {
this.voltage = voltage;
}
public double getBrightness() {
return brightness;
}
public void setBrightness() {
if (voltage <= 9) {
this.brightness = 0;
} else if (voltage <= 10) {
this.brightness = voltage * 50.0 - 450;
} else if (voltage <= 220) {
this.brightness = voltage * (5 / 7.0) + (300 / 7.0);
} else {
this.brightness = 200;
}
}
public void show() {
System.out.println("@" + name + ":" + (int) Math.floor(getBrightness()));
}
}
class DaylightLamp extends ControlledEquipment {//日光燈類
private double brightness = 180;
public DaylightLamp() {
resistance = 5;
}
public void setVoltage(double voltage) {
this.voltage = voltage;
}
public double getBrightness() {
return this.brightness;
}
public void setBrightness() {
if (voltage != 0) {
this.brightness = brightness;
} else {
this.brightness = 0;
}
}
public void show() {
System.out.println("@" + name + ":" + (int) Math.floor(getBrightness()));
}
}
class ContinueGovernor extends ControlEquipment {//連續調速器類
private double position = 0.00;
public void setPosition(double position) {
if (position >= 0.0 && position <= 1.0) {
this.position = position;
}
}
public double getPosition() {
return this.position;
}
public double getOutputVoltage(double inputVoltage) {
return getPosition() * inputVoltage;
}
public void show() {
System.out.println("@" + name + ":" + String.format("%.2f", position));
}
}
class SplitGovernor extends ControlEquipment {//分檔調速器類
private int gear = 0;
public void upGear() {
if (gear < 3)
this.gear ++;
}
public void downGear() {
if (gear > 0)
this.gear --;
}
public double getOutputVoltage(double inputVoltage ) {
switch (gear) {
case 0:
return 0;
case 1:
return inputVoltage * 0.3;
case 2:
return inputVoltage * 0.6;
case 3:
return inputVoltage * 0.9;
default:
return 0;
}
}
public void show() {
System.out.println("@" + name + ":" + gear);
}
}
class Switch extends ControlEquipment {//開關類
protected int count = 1;
private int state = 0;
public void open() {
this.state = 1;
}
public void close() {
this.state = 0;
}
public void setState() {
this.count ++;
if (this.count % 2 == 0) {
this.state = 1;
} else
this.state = 0;
}
public int getState() {
return state;
}
public void show() {
if (state == 1)
System.out.println("@" + name + ":closed");
else
System.out.println("@" + name + ":turned on");
}
}
以下是程式碼的類圖
這次的“家居強電電路模擬程式-2”在“家居強電電路模擬程式-1”的基礎上迭代增加了新的落地扇,並增加了並聯電路,難度上升
這次的作業給電路裝置新增了電阻這一屬性,並且輸入的格式發生變化,因此需要新增類來處理變化。
透過類圖可以看出,這次的類增加了許多,也變得更加複雜,耦合性比較強,因為個人能力有限,無法做到更好,並且這次作業並沒有拿到分數,問題主要出在輸出問題以及電路中各個裝置的計算,輸出的裝置數值均為初始值並沒有完成計算步驟。
先來分析新增的幾個重要的類:
InputCircuitProcessing(輸入電路處理類):
這個類用於處理並聯電路的輸入字串。
它包含一個方法獲取串聯電路裝置(getSeriesEquipment),該方法接收一個字串列表,代表電路元件,以及一個新的系列電路的名稱,然後返回一個包含這些元件的 SeriesCircuit 物件。
InputProcessing(輸入處理類):
這個類用於處理輸入的字串,判斷是裝置還是操作。
它包含兩個屬性:裝置名稱(equipmentName)和輸入操作(operation),分別用於儲存裝置的名稱和操作的命令。
包含一個方法,用於解析輸入字串,判斷其型別,並設定屬性 equipmentName 和 operation。
SplitCircuitEquipment(分割電路裝置類):
這個類包含一個靜態方法 splitCircuit,該方法接收一個字串,並返回一個字串列表,代表方括號內的電路元件。這個方法使用正規表示式來匹配方括號內的內容,並將匹配到的內容新增到列表中。
ParallelCircuitProcessing(並聯電路處理類):
這個類用於處理並聯電路的裝置。它包含一個屬性串聯電路裝置(seriesEquipments),用於儲存並聯電路中的串聯電路裝置。這個類還包含一個方法獲取串聯電路裝置(getSeriesEquipment),該方法接收一個字串列表,代表電路元件,以及一個新的系列電路的名稱,然後返回一個包含這些元件的 SeriesCircuit 物件。這個方法使用了JudgeEquipment類來判斷每個元件的型別,並新增到串聯電路中。
JudgeEquipment(裝置判斷類):
這個類經過修改後,用於判斷輸入的字串代表的裝置型別。它包含兩個列表 allCircuit 和 allParallel,用於儲存所有電路裝置和並聯電路裝置。
包含一個方法判斷電路裝置(judge),該方法接收一個代表裝置或操作的字串,如果它是一個已知的裝置,則返回相應的 ElectricEquipment 物件,如果它沒有被識別,則返回 null。此外,還有一個方法 judgeCircuitM,用於判斷並聯電路中的電路名稱是否匹配已知的並聯電路裝置。
Calculation(計算類):
這個類包含一個串SeriesCircuit 型別的屬性 seriesCircuit 和一個 Calculate 型別的屬性 calculate。
方法 ResistanceCalculation接收一個 SeriesCircuit 物件,呼叫 calculate 類的 calculateResistance 方法來計算電路的電阻,並返回更新後的 SeriesCircuit 物件。
方法 calculation接收一個 SeriesCircuit 物件,並進行一系列計算操作。它首先遍歷電路中的所有裝置,根據裝置型別和電路狀態進行相應的計算。這個方法還涉及到遞迴呼叫 calculation 方法來處理並聯電路中的裝置。最終,它返回一個新的 SeriesCircuit 物件,其中包含了計算後的裝置。
Calculate(計算輔助類):
這個類包含多個用於計算電路引數的方法。
方法 calculate接收一個 ElectricEquipment 物件、電壓 v 和電阻 r,根據裝置型別執行不同的計算,並返回更新後的 ElectricEquipment 物件。
方法 calculateResistance(ElectricEquipment T) 接收一個 ElectricEquipment 物件,計算並返回該裝置的電阻。這個方法涉及到遞迴地呼叫 calculateResistance 來處理並聯電路中的裝置,並將它們的電阻相加。
回到問題所在,裝置無法獲取經過計算後的資料主要出現在Calculation類和Calculate類中,這個問題我將會在接下來的迭代題目中將其解決。
總的來說,”家居強電電路模擬程式-2“透過引入新的裝置、增加並聯電路的支援和新增電阻屬性,使得電路模擬更加真實和複雜。但因為”家居強電電路模擬程式-2“的類結構設計並不是很好,所以在迭代修改時還是有點困難,這尤其體現出好的類結構設計的重要性。所以我決定在接下來的題目中,重新設計類結構,儘量遵循開閉原則、單一職責原則以及里氏替換原則等原則,給出一個良好設計的類結構。
三、踩坑心得
在進行類結構設計與寫程式碼時,我遇到了許多問題,也從中吸取了許多教訓。以下是我的一些踩坑心得:
1、耐心和毅力至關重要:我常常因為遇到難題而感到沮喪,甚至想要放棄。但是,只有堅持下去,才能解決問題,提高自己的能力。
2、良好的設計原則:在設計類結構時,遵循良好的設計原則非常重要。這些原則包括單一職責原則、開閉原則、里氏替換原則等。它們可以幫助我們建立出可擴充套件、可維護的程式碼。
3、模組化設計:將系統劃分為獨立的、可替換的模組,可以提高程式碼的可維護性和可擴充套件性。每個模組都應該有一個清晰定義的功能,並且與其他模組的耦合度儘量低。
4、考慮未來的需求:在設計類結構時,要考慮到未來的需求,為可能的擴充套件留下空間。例如,我可以為處理不同題型的類留出擴充套件點,以應對未來的題目變化。
5、不斷學習和改進:在設計類結構時,我意識到自己的能力還有很大的提升空間。我需要不斷學習,瞭解更多的設計模式和原則,以便在遇到問題時能夠更好地解決問題。
6、程式碼審查和測試:在完成類結構設計後,進行程式碼審查和測試非常重要。這可以幫助我發現潛在的問題,並及時修復。
總的來說,軟體工程是一個需要耐心、學習和實踐的過程。透過不斷地嘗試和改進,我相信我會成為一個更好的程式設計師。
四、改進建議
1、使用抽象類:定義清晰的抽象類,可以讓更容易地擴充套件新的題型或裝置。當需要新增新功能時,可以直接建立一個新的子類,而不用修改現有的類。
2、降低耦合度:儘量減少類之間的依賴關係,比如定義一個控制類Control或管理類Agent這樣可以更容易地修改和維護程式碼。
3、程式碼複用:儘量程式碼複用,這樣可以減少程式碼冗餘,並使程式碼更加清晰。
4、學習和應用設計模式:這一點很重要,瞭解並應用設計模式,可以幫助解決常見的設計問題,並提高程式碼的可維護性與可擴充套件性。
5、除錯程式碼:學會使用除錯工具,如斷點除錯、日誌輸出等,可以幫助更快地找到並修復錯誤。
6、基礎語法:熟練掌握基礎語法,學會使用各種包中的類和方法,可以有效的幫助我們完成程式碼。
五、總結
在PTA作業的第二階段,我主要寫了三個程式的設計與實現,這三個程式分別為“答題判題程式-4”、“家居強電電路模擬程式-1”及其迭代版本“家居強電電路模擬程式-2”。在這個過程中,我深刻認識到自己在程式設計能力和問題解決能力上的不足,並從中吸取了許多教訓。
首先,我在電路模擬程式的設計與實現上取得了顯著的成長。在這三次作業中,我從零開始,逐步構建和完善了電路模擬系統,這個過程讓我深刻體會到了程式設計、類結構設計以及問題解決的重要性。
其次,我在“答題判題程式-4”的實現上缺乏耐心和毅力,導致程式碼未能完成。這讓我意識到耐心和毅力對於解決問題的重要性。我在程式碼設計和實現上缺乏經驗,沒有充分考慮到可擴充套件性和可維護性。因此,在“家居強電電路模擬程式”的設計中,我吸取了答題判題程式的教訓,設計了很多類來實現單一職責原則。
最後,我也意識到自己在程式設計能力和問題解決能力上還存在不足。在實際編寫程式碼時,我常常因為能力有限而無法達到預期的效果。這讓我深刻反思,認識到我需要不斷學習和改進,提升自己的程式設計技能和問題解決能力。
總的來說,這次PTA作業讓我收穫頗豐。我不僅更深刻的認識了類結構設計以及如何設計出良好的類結構,更學會了如何提升自己的程式設計能力和問題解決能力。