一、前言
关于7,8两次家具强电电路模拟程序,我认为是比较困难且综合的程序题,我们需要处理复杂的电路结构,如包含多个并联电路的串联电路,以及并联电路之间的包含关系还要精确地处理输入和输出格式,确保所有的计算和输出都符合题目要求,这些设计程序整体的方面都属于较为困难的,而关于类和对象的关系,以及如何通过方法来模拟电路的工作原理,这种在动手编写时具体补充的代码部分难度偏向中等,知识点我个人认为偏向基础的面向对象编程(如需要设计多个类对象、方法、变量、数据类型、控制结构等。),数据结构/数组与集合(选择合适的数据结构去储存设备信息和连接信息)和字符串处理。至于题目题量则是单一题目,但涉及多个类和复杂逻辑。总之是个复杂的Java程序模拟题。
二、设计与分析
首先是粗略的分析即如何完成程序
1,设计电路设备类:设计一个通用的电路设备类,包含所有电路设备的公共属性和方法。
2,受控设备与控制设备类:分别设计受控设备类和控制设备类,并实现具体的设备如开关、调速器、灯、风扇等。
3,串联电路与并联电路类:设计串联电路和并联电路类,实现电路的串联和并联逻辑。
4,输入处理:解析输入信息,构建电路设备对象,并建立设备之间的连接关系。
5,计算电路状态:根据输入的控制信息,计算电路的状态,包括开关状态、调速器的档位、灯的亮度、风扇的转速等。
6,输出结果:按照题目要求的格式输出所有设备的状态或参数。
由于都是家具强电电路模拟程序所以大致思路如此,但重点还是在于迭代的改变和怎么合理的设计并完成程序。
第七次题目集
点击查看代码
import java.util.*;public class Main {private static Map<String, Device> devices = new HashMap<>();private static Map<String, Connection> connections = new HashMap<>();private static Map<String, Circuit> circuits = new HashMap<>();public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String input;while (!(input = scanner.nextLine()).equals("end")) {processInput(input);}scanner.close();simulateCircuit();printDeviceStatus();}private static void processInput(String input) {if (input.startsWith("#T")) {processSeriesCircuit(input);} else if (input.startsWith("#M")) {processParallelCircuit(input);} else if (input.startsWith("#")) {processDeviceControl(input);}}private static void processSeriesCircuit(String input) {String[] parts = input.split(":");String circuitId = generateUniqueId();String[] connections = parts[1].split(" ");Circuit circuit = new Circuit(circuitId);for (String connection : connections) {circuit.addConnection(connection);}circuits.put(circuitId, circuit);}private static void processParallelCircuit(String input) {String[] parts = input.split(":");String circuitId = generateUniqueId();String[] seriesCircuits = parts[1].substring(1, parts[1].length() - 1).split(" ");Circuit parallelCircuit = new Circuit(circuitId);for (String seriesCircuit : seriesCircuits) {parallelCircuit.addSeriesCircuit(circuits.get(seriesCircuit));}circuits.put(circuitId, parallelCircuit);}private static void processDeviceControl(String input) {String[] parts = input.split(":");String deviceId = parts[0].substring(1);Device device = devices.get(deviceId);if (device != null) {device.control(parts[1]);}}private static void simulateCircuit() {for (Circuit circuit : circuits.values()) {circuit.simulate();}}private static void printDeviceStatus() {devices.values().forEach(Device::printStatus);}private static String generateUniqueId() {String id = UUID.randomUUID().toString();while (circuits.containsKey(id) || devices.containsKey(id)) {id = UUID.randomUUID().toString();}return id;}private static abstract class Device {protected String id;public Device(String id) {this.id = id;}public abstract void control(String command);public abstract void printStatus();public abstract void updateState();}private static class Switch extends Device {private boolean state = false;public Switch(String id) {super(id);}@Overridepublic void control(String command) {state = !state;}@Overridepublic void printStatus() {System.out.println("@" + id + ":" + (state ? "closed" : "turned on"));}@Overridepublic void updateState() {if (this.state==false) {this.state=true;}else if(this.state==true) {this.state=false;} }public boolean isState() {return state;}}private static class Dimmer extends Device {private double level = 0.0;public Dimmer(String id) {super(id);}@Overridepublic void control(String command) {if (command.equals("+")) {level += 0.1;} else if (command.equals("-")) {level -= 0.1;}}@Overridepublic void printStatus() {System.out.printf("@%s:%.2f\\\\\\\\n", id, level);}@Overridepublic void updateState() {// Update dimmer state based on current circuit conditions}}private static class Bulb extends Device {private int brightness = 0;public Bulb(String id) {super(id);}@Overridepublic void control(String command) {// No control needed for bulbs in this simulation}@Overridepublic void printStatus() {System.out.println("@" + id + ":" + brightness);}@Overridepublic void updateState() {// Update bulb state based on current circuit conditions}public void setBrightness(int brightness) {this.brightness = brightness;}}private static class Fan extends Device {private int speed = 0;public Fan(String id) {super(id);}@Overridepublic void control(String command) {// No control needed for fans in this simulation}@Overridepublic void printStatus() {System.out.println("@" + id + ":" + speed);}@Overridepublic void updateState() {// Update fan state based on current circuit conditions}public void setSpeed(int speed) {this.speed = speed;}}private static class Circuit {private String id;private List<Connection> connections = new ArrayList<>();private List<Circuit> seriesCircuits = new ArrayList<>();public Circuit(String id) {this.id = id;}public void addConnection(String connection) {connections.add(new Connection(connection));}public void addSeriesCircuit(Circuit circuit) {seriesCircuits.add(circuit);}public void simulate() {for (Connection connection : connections) {Device controlDevice = devices.get(getDeviceIdFromPin(connection.getInputPin()));if (controlDevice instanceof Switch && ((Switch) controlDevice).isState()) {updateConnectedDevice(connection.getOutputPin(), true);} else {updateConnectedDevice(connection.getOutputPin(), false);}}}private String getDeviceIdFromPin(String pin) {return pin.split("-")[0];}private void updateConnectedDevice(String outputPin, boolean isOn) {Device device = devices.get(getDeviceIdFromPin(outputPin));if (device instanceof Bulb) {((Bulb) device).setBrightness(isOn ? 200 : 0);} else if (device instanceof Fan) {((Fan) device).setSpeed(isOn ? 360 : 0);}}}private static class Connection {private String inputPin;private String outputPin;private boolean connectedDeviceState;public Connection(String connection) {String[] parts = connection.split("-");inputPin = parts[0];outputPin = parts[1];connectedDeviceState = false;}public String getInputPin() {return inputPin;}public String getOutputPin() {return outputPin;}
}}
点击查看代码
class Device {protected double v1;protected double v2;public Device() {}public Device(double v1,double v2) {this.v1=0;this.v2=0;}public double getV1() {return v1;}public void setV1(double v1) {this.v1 = v1;}public double getV2() {return v2;}public void setV2(double v2) {this.v2 = v2;}public void display() {}}
import java.util.*;
class Circuit {protected static LinkedHashMap<String,Device> deviceMap = new LinkedHashMap<>();public Circuit() {}public void update() {Device previous =null;for(Device device : deviceMap.values()) {if(previous!=null) {device.setV1(previous.getV2());}if(device instanceof Switch) {((Switch) device).update();}else if(device instanceof Gearspeed) {((Gearspeed) device).update();}else if(device instanceof Unitgear) {((Unitgear) device).update();}else if(device instanceof Light1) {((Light1) device).update();}else if(device instanceof Light2) {((Light2) device).update();}else if(device instanceof Fan) {((Fan) device).update();}else if(device instanceof Fan2){((Fan2)device).update();}previous=device;}}public void getDeviceStates() {for (Map.Entry<String, Device> entry : deviceMap.entrySet()) {System.out.print("@" + entry.getKey() + ":");entry.getValue().display();}}
class device1 extends Device {public device1(double v1,double v2) {this.v1=v1;this.v2=v2;}public device1() {}}class device2 extends Device{protected double v;public device2() {}public device2(double v1,double v2,double v) {this.v1=v1;this.v2=v2;this.v=v;}}
class Fan extends device2{private double lux=0;public Fan(double v,double v1,double v2,double lux) {super(v,v1,v2);this.lux=0;}public Fan() {}public double getLux() {return lux;}public void setlux(double lux) {this.lux=lux;}public void update() {if(this.v1<80) {this.lux=0;}if(this.v1>=80&&this.v1<=150) {this.lux=4*this.v1-240;}if(this.v1>=150) {this.lux=360;}}public void display() {System.out.println(Math.round(this.lux));}
}class Fan2 extends device2{private double lux=0;public Fan2(double v,double v1,double v2,double lux) {super(v,v1,v2);this.lux=0;}public Fan2() {}public double getLux() {return lux;}public void setlux(double lux) {this.lux=lux;}public void update() {if(this.v1<80) {this.lux=0;}if(this.v1>=80&&this.v1<=100) {this.lux=80;}if(this.v1>=100&&this.v1<120) {this.lux=160;}if(this.v1>=120&&this.v1<140){this.lux=260;}if(this.v1>=140){this.lux=360;}}public void display() {System.out.println(Math.round(this.lux));}
}class Gearspeed extends device1{private double v1 = 220;private int gear=0;public Gearspeed() {}public Gearspeed(int gear,double v1,double v2) {super(v1,v2);this.gear=gear;this.gear=0;}public int getGear() {return gear;}public void up() {if(this.gear<3)this.gear++;}public void down() {if(this.gear>0)this.gear--;}public void update() {if (this.v1 == 0) {this.v2 = 0;} else {switch (this.gear) {case 0:this.v2 = 0;break;case 1:this.v2 = 0.3 *this.v1;break;case 2:this.v2 = 0.6 *this.v1;break;case 3:this.v2 = 0.9 * this.v1;break;default:this.v2 = 0;break;}}}public void display() {System.out.println(this.gear);}
}class Light1 extends device2{private double v2 = 0;private double lux=0;public Light1(double v,double v1,double v2,double lux) {super(v,v1,v2);this.lux=0;}public Light1() {}public double getLux() {return lux;}public void update() {if(this.v1>=0&&this.v1<=9) {this.lux=0;}else if(this.v1>9&&this.v1<=220) {this.lux=(5.0/7.0)*v1+(300.0/7.0);}else if(this.v1>220) {this.lux=200;}}public void display() {System.out.println((int)(this.lux));}
}class Light2 extends device2{private double v2 = 0;private double lux=0;public Light2(double v,double v1,double v2,double lux) {super(v,v1,v2);this.lux=0;}public Light2() {}public double getLux() {return lux;}public void update() {if(this.v1>0) {this.lux=180;}else if(this.v1==0) {this.lux=0;}}public void display() {System.out.println((int)this.lux);}
}import java.util.*;
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);Circuit circuit = new Circuit();Device device = new Device();while(true) {String input = scanner.next();if(input.startsWith("[")) {String regex = "[A-Z]\\d+-2";Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(input);while(matcher.find()) {String inputs = input.substring(1,3);if(inputs.startsWith("K")) {Device switchs = new Switch();Circuit.deviceMap.put(inputs, switchs);}else if(inputs.startsWith("F")) {Device gears = new Gearspeed();circuit.deviceMap.put(inputs, gears);}else if(inputs.startsWith("L")) {Device unit = new Unitgear();circuit.deviceMap.put(inputs, unit);}else if(inputs.startsWith("B")) {Device light1 = new Light1();circuit.deviceMap.put(inputs, light1);}else if(inputs.startsWith("R")) {Device light2 = new Light2();circuit.deviceMap.put(inputs, light2);}else if(inputs.startsWith("D")) {Device fan = new Fan();Circuit.deviceMap.put(inputs, fan);}else if(inputs.startsWith("A")){Device fan2=new Fan2();Circuit.deviceMap.put(inputs, fan2);}if(Circuit.deviceMap.size()==1){Circuit.deviceMap.get(inputs).setV1(220);}}}else if(input.startsWith("#K")) {for(Map.Entry<String,Device>entry : circuit.deviceMap.entrySet()) {if(entry.getKey().startsWith("K")) {((Switch) entry.getValue()).setState();break;}}}else if(input.startsWith("#F")) {for(Map.Entry<String,Device>entry : circuit.deviceMap.entrySet()) {if(entry.getKey().startsWith("F")) {if(input.substring(3,4).equals("+")) {((Gearspeed) entry.getValue()).up();}else if(input.substring(3,4).equals("-")) {((Gearspeed) entry.getValue()).down();}break;}}}else if(input.startsWith("#L")) {for(Map.Entry<String,Device>entry : circuit.deviceMap.entrySet()) {if(entry.getKey().startsWith("L")) {double input1 = Double.parseDouble(input.substring(4));((Unitgear) entry.getValue()).setGear(input1);break;}}}else if(input.equals("end")) {break;}}circuit.update();circuit.getDeviceStates();}}
class Switch extends device1{private int state;public Switch() {}public Switch(double v1,double v2,int state) {super(v1,v2);this.state=0;}public int getState() {return this.state;}public void setState() {if (this.state==1) {this.state=0;}else if(this.state==0) {this.state=1;}}public void update() {if(this.state==1) {this.v2=this.v1;}else if(this.state==0) {this.v2=0;}}public void display() {if(this.state==0) {System.out.println("tuened on");}else if(this.state==1) {System.out.println("closed");}}
}import java.text.DecimalFormat;
class Unitgear extends device1{private double v1 = 220;private double gear=0;public Unitgear() {}public Unitgear(double gear,double v1,double v2) {super(v1,v2);if(gear>=0&&gear<=1)this.gear=gear;this.gear=0;}public double getGear() {return gear;}public void setGear(double gear) {if(gear>=0&&gear<=1)this.gear = gear;}public void update() {this.v2=((double)this.v1*this.gear);}public void display() {DecimalFormat decimalFormat = new DecimalFormat("#0.00");String format = decimalFormat.format(this.gear);System.out.println(format);}
}
关于代码的分析
首先是定义Device抽象类(设备)通过此来控制所有设备的基础行为,其子类分为两种,一是控制设施二是受控设备,接下来是电路类,首先是串联电路进行模拟电路,其次是并联电路由多个串联电路构成模拟多个分支电路,然后再单独设计一个连接类,去处理字符串的问题并且将输入,输出引脚连接而主类则负责处理输入,解析输入信息,创建设备、电路和连接。模拟电路调用电路的模拟方法来更新设备状态,输出所有设备的状态。
关于程序/题目的分析
1,储存数据
创建一个类来表示电路中的每个设备,包含设备类型、编号、状态、引脚电压等信息,再从基础设备类继承出具体的设备类。创建一个类来表示电路,包含所有设备的集合以及连接信息,串联电路直接按顺序连接引脚,并联电路则需要将多个串联电路的输入和输出引脚短接。
2,update(更新状态,处理输入)
具体分为设备状态和电路状态,一设备状态根据输入的控制信息更新设备状态,二电路状态在模拟电路时,根据设备的状态计算每个引脚的电压,并更新设备的工作状态(如灯泡亮度、风扇转速等)。
3,输入(字符串解析)
解析输入信息,包括设备信息、连接信息、控制设备调节信息等。
4,电路检测(第八次)
检测电路中是否存在短路及在电流计算过程中,检查是否有设备电流超过其最大限制,并作出相应处理。
5,输出模块
按照指定格式输出每个设备的状态和引脚电压和错误提示在检测到短路或电流超限时,输出相应的错误提示。
具体实现分析
设备类设计:
Device 抽象类:包含所有设备的基本属性和方法。
ControlDevice 和 ControlledDevice 类:分别继承自 Device,实现具体的设备逻辑。
电路类设计:
SeriesCircuit 和 ParallelCircuit 类:分别表示串联和并联电路,实现电路的模拟逻辑。
输入处理:
InputHandler 类:负责解析输入信息,构建设备对象,并建立设备之间的连接关系。
计算电路状态:
CircuitSimulator 类:根据输入的控制信息,计算电路的状态,包括开关状态、调速器的档位、灯的亮度、风扇的转速等。
输出结果:
OutputHandler 类:按照题目要求的格式输出所有设备的状态或参数。
在设计过程中,我的最大的挑战在于如何合理地组织类和方法,通过定义清晰的接口和继承关系,可以有效地减少代码冗余并提高复用性。同时,对于复杂的逻辑处理(如短路检测、电流限制等),需要仔细设计并多次测试以确保正确性(是的根本不知道错在哪里反复调试是最崩溃的)。
三、采坑心得
首先就是短路检测不准确,在运行实现短路检测时,由于未考虑到所有可能的短路情况(如通过互斥开关的间接短路还有间接短路可能涉及多个设备和连接,除了直接检查电源到地的路径外,还需要考虑通过中间设备(如开关、互斥开关)的间接连接以及动态电路变化在电路模拟过程中,设备的状态(如开关的开合)可能会发生变化,这会影响短路路径的存在与否。),导致检测结果不准确。这就导致只能遍历电路或调试查看电路,检查是否存在从电源到地的低电阻路径。之后则是电流计算错误在计算设备电流时,未考虑到设备电阻随状态变化(如二极管导通时电阻为0,这点使我困扰了很久因为各部分电阻不同,而我把电路设备写进电路,各路电流还是要分各种情况计算),导致计算结果不准确。所以只能在电流计算过程中,根据设备的当前状态动态调整其电阻值,并重新计算电流。还有设备状态更新逻辑错误,设备的更新逻辑复杂,容易遗漏某些情况。只能用每部分查看来验证每个设备的状态更新逻辑。最后是输入解析错误(也是我出现的最为频繁的问题,但我看到一大堆报错或者啥也没有的时候,我就知道又需要我坐牢了)在解析输入信息时,由于输入格式复杂且多样,容易出现解析错误导致程序崩溃这里面最常见的还是字符串解析错误,输入信息的格式复杂,解析时容易出错。。所以只能增加输入验证逻辑,确保输入信息符合预定格式。同时,使用异常处理机制捕获并处理可能的输入错误。
四、改进建议
全面考虑短路路径:在短路检测算法中,不仅要检查从电源到地的直接路径,还要遍历整个电路图,考虑通过中间设备(如开关、互斥开关)的间接短路路径。
动态检测:由于电路中的设备状态可能会随着模拟的进行而发生变化(如开关的开合),因此短路检测不应该是静态的,而应该在每次设备状态更新后都重新执行。
动态电阻模型:为电路中的每个设备建立一个动态电阻模型,该模型能够根据设备的当前状态(如二极管的导通与截止)动态地调整其电阻值。在电流计算过程中,根据这些动态电阻值来求解电路方程。
迭代求解:由于电路中的电流和电压是相互依赖的,可能需要采用迭代方法来求解电路方程。在每次迭代中,根据当前的电压分布计算电流,然后根据计算出的电流更新电压分布,直到电压和电流都收敛到稳定值。
完善设备状态更新逻辑:对设备状态更新逻辑进行详细的审查和测试,确保覆盖所有可能的场景。
代码重构和优化:对代码进行重构,确保类和方法的职责清晰,减少代码冗余,提高代码的可读性和可维护性。
增强输入处理能力:严格的输入验证,在解析输入信息之前,增加严格的输入验证步骤,确保输入数据符合预定的格式和规范。
模块化设计:将程序划分为多个模块,每个模块负责特定的功能。通过清晰的接口和继承关系来组织类和方法,减少代码冗余并提高复用性。
五、总结
总结
在本次家具强电电路模拟程序的编写过程中,是一个复杂且综合的编程挑战。该程序不仅需要处理复杂的电路结构(包括串联、并联以及它们之间的嵌套关系),还需要精确地解析输入信息、计算电路状态,并按照特定格式输出设备状态及参数。通过深入分析和设计,需要逐步构建了包括设备类、电路类、输入处理、状态计算和输出模块在内的完整程序框架。
在设计和实现过程中,我深刻体会到了面向对象编程(OOP)的强大之处,通过定义清晰的接口和继承关系,可以有效地减少了代码冗余,提高了代码的复用性和可维护性。同时,我们也面临了诸多挑战,如短路检测的复杂性、电流计算的动态性、设备状态更新的多样性以及输入解析的易错性等。
通过不断的调试和优化,逐步解决了这些问题。在短路检测方面,意识到需要全面考虑所有可能的短路路径,包括通过中间设备的间接短路,并在每次设备状态更新后重新执行短路检测。在电流计算方面,引入了动态电阻模型,根据设备的当前状态动态调整电阻值,并采用迭代方法求解电路方程。在设备状态更新和输入解析方面,增加了详细的审查和测试步骤,以确保逻辑的正确性和输入的有效性。
此外,我还提出了多项改进建议,旨在进一步提高程序的健壮性、可维护性和可扩展性。这些建议包括完善短路检测算法、优化电流计算方法、重构和优化代码结构、增强输入处理能力以及采用模块化设计等。
总之,家具强电电路模拟程序的开发过程不仅考验了我的编程技能,也让我深刻理解了面向对象编程和数据结构在实际应用中的重要性。