题目集4~6的总结Blog

news/2025/2/25 7:23:21/文章来源:https://www.cnblogs.com/61119gfh55/p/18565174

题目一:答题程序设计与实现
功能解析
题目一要求设计一个模拟答题系统,功能包括:

题目管理:
输入题目信息,包括题号、内容和标准答案。
支持删除某些题目,使其无效化。
试卷管理:
输入试卷信息,包括试卷编号、包含的题目及每题分值。
验证试卷总分是否满足预设标准(如 100 分)。
学生答题管理:
输入学生信息和答题记录。
根据试卷信息和学生答案对比计算得分。
结果输出:
输出每个题目的答题结果(正确、部分正确或错误)。
输出学生得分及答题详情。
代码设计与关键模块
代码主要采用了面向对象设计,核心类包括:

Question:表示一个题目,包含题号、题干、标准答案及状态信息。
TestPaper:表示一张试卷,记录试卷编号、题目列表及分值分布。
Answer:表示一个学生提交的答案,包含学生编号、答题记录及对应得分。
Student:表示学生信息,包括学号和姓名。

类与方法详解

  1. Question 类
    表示一道题目的基本信息。

属性:
num:题号(int)。
questions:题干内容(String)。
answer:标准答案(String)。
isTrue:题目是否有效(boolean)。
方法:
getNum():获取题号。
getAnswer():获取标准答案。
isIstrue():判断题目是否有效。
setIstrue(boolean):设置题目状态(有效/无效)。
示例:

Question q1 = new Question(1, "What is 2+2?", "4");
System.out.println(q1.getAnswer()); // 输出: 4
2. TestPaper 类
表示一张试卷及其结构。

属性:
count:试卷编号(int)。
nums:包含的题号列表(ArrayList)。
scores:对应题号的分值列表(ArrayList)。
方法:
getCount():获取试卷编号。
getNum():获取题号列表。
getScore():获取题目分值列表。
示例:

ArrayList nums = new ArrayList<>(Arrays.asList(1, 2, 3));
ArrayList scores = new ArrayList<>(Arrays.asList(10, 20, 30));
TestPaper test1 = new TestPaper(101, nums, scores);
System.out.println(test1.getScore()); // 输出: [10, 20, 30]
3. Answer 类
表示学生提交的一份答卷及答题记录。

属性:
num:试卷编号(int)。
id:学生编号(String)。
number:答题号列表(ArrayList)。
answers:学生的答案列表(ArrayList)。
scores:对应每题的得分列表(ArrayList)。
方法:
getNum():获取试卷编号。
getAnswers():获取学生答案列表。
getScores():获取得分列表。
setScores(ArrayList):设置得分列表。
示例:

ArrayList numbers = new ArrayList<>(Arrays.asList(1, 2));
ArrayList answers = new ArrayList<>(Arrays.asList("4", "3"));
Answer ans1 = new Answer(101, "20230001", numbers, answers);
System.out.println(ans1.getAnswers()); // 输出: [4, 3]
4. Student 类
表示一个学生的基本信息。

属性:
id:学号(String)。
name:姓名(String)。
方法:
getId():获取学号。
getName():获取姓名。
示例:

Student stu1 = new Student("20230001", "Alice");
System.out.println(stu1.getName()); // 输出: Alice
主类 Main 的解析
主类 Main 是答题程序的核心执行模块,其功能涵盖了:

数据的输入与解析:
解析题目信息、试卷信息、学生信息和答题记录。
校验输入格式是否正确,并将数据存储到对应的对象和列表中。
功能实现:
管理题目和试卷的动态操作,如删除题目。
根据试卷与答题记录,对学生答案进行比对,计算得分。
结果输出:
输出每道题的答题情况(正确、部分正确、错误)。
输出学生的总得分及得分详情。
核心结构与功能模块
Main 类由以下几部分组成:

  1. 数据存储与初始化
    使用多个集合存储不同数据类型:
    questionlist:存储所有题目。
    testList:存储所有试卷。
    studentArrayList:存储所有学生。
    answerArrayList:存储所有答题记录。
    delList:存储被标记为删除的题目编号。
    代码示例:

ArrayList questionlist = new ArrayList<>();
ArrayList testList = new ArrayList<>();
ArrayList studentArrayList = new ArrayList<>();
ArrayList answerArrayList = new ArrayList<>();
ArrayList delList = new ArrayList<>();
2. 输入解析与处理
(1) 解析题目输入
通过正则表达式提取题目信息(如编号、题干、标准答案)。
创建 Question 对象并添加到 questionlist。
代码示例:

if (input.startsWith("#N:")) {
String pattern = "#N:(\d+) #Q:(.+) #A:(\d+)";
Pattern p = Pattern.compile(pattern);
Matcher question = p.matcher(input);
if (question.find()) {
Question qs = new Question(
Integer.parseInt(question.group(1)),
question.group(2),
question.group(3)
);
questionlist.add(qs);
} else {
System.out.println("wrong format:" + input);
}
}
功能:
通过正则表达式校验输入格式。
如果校验通过,将题目信息存入对象中。
(2) 解析试卷输入
试卷输入格式包含试卷编号、题号列表及其对应分值。
正则提取题号和分值后,创建 TestPaper 对象并存储。
代码示例:

else if (input.startsWith("#T:")) {
String testPattern = "^#T:(\d+)(?: (\d+-\d+))*";
Pattern testP = Pattern.compile(testPattern);
Matcher test = testP.matcher(input);
if (test.matches()) {
int count = Integer.parseInt(test.group(1));
ArrayList questionnum = new ArrayList<>();
ArrayList scorelist = new ArrayList<>();

    Pattern pp = Pattern.compile("(\\d+)-(\\d+)");Matcher m = pp.matcher(input);while (m.find()) {questionnum.add(Integer.parseInt(m.group(1)));scorelist.add(Integer.parseInt(m.group(2)));}TestPaper newTest = new TestPaper(count, questionnum, scorelist);testList.add(newTest);
} else {System.out.println("wrong format:" + input);
}

}
(3) 解析学生与答题记录
学生信息:
格式:#X:<学生编号> <学生姓名>。
创建 Student 对象并存入 studentArrayList。
答题记录:
格式:#S:<试卷编号> <学生编号> #A:<题号>-<答案>。
提取答题记录及答案,创建 Answer 对象。
代码示例:

else if (input.startsWith("#X:")) {
String pattern = "(\d{8})\s(\w+)";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(input);
while (m.find()) {
String id = m.group(1);
String name = m.group(2);
Student newStudent = new Student(id, name);
studentArrayList.add(newStudent);
}
}
else if (input.startsWith("#S:")) {
String pattern = "^#S:(\d+) (\d{8}) ((?:#A:\d+-[\w\s]+)+)";
Pattern answerPattern = Pattern.compile(pattern);
Matcher m = answerPattern.matcher(input);
if (m.matches()) {
int count = Integer.parseInt(m.group(1));
String ID = m.group(2);
String answersPart = m.group(3);
ArrayList nums = new ArrayList<>();
ArrayList answers = new ArrayList<>();

    Pattern answerMatcher = Pattern.compile("#A:(\\d+)-(\\w+)");Matcher ansMatcher = answerMatcher.matcher(answersPart);while (ansMatcher.find()) {nums.add(Integer.parseInt(ansMatcher.group(1)));answers.add(ansMatcher.group(2));}Answer newAnswer = new Answer(count, ID, nums, answers);answerArrayList.add(newAnswer);
} else {System.out.println("wrong format:" + input);
}

}
展开
3. 题目删除逻辑
支持通过 #D:<题号> 格式输入,标记题目为无效。

代码示例:

else if (input.startsWith("#D:")) {
String pattern = "^#D:N-(\d+)";
Pattern delp = Pattern.compile(pattern);
Matcher m = delp.matcher(input);
if (m.find()) {
delList.add(Integer.parseInt(m.group(1)));
for (int i : delList) {
for (int j = 0; j < questionlist.size(); j++) {
if (questionlist.get(j).getNum() == i) {
questionlist.get(j).setIstrue(false);
}
}
}
} else {
System.out.println("wrong format:" + input);
}
}
4. 答题结果计算与输出
根据试卷中的题号,从题目列表中查找对应题目。
对比学生答案和标准答案,判断答题结果:
全对:得满分。
部分正确:得一半分。
错误或无效题目:得 0 分。
代码示例:

for (TestPaper paper : testList) {
if (paper.getCount() == newAnswer.getNum()) {
for (int i = 0; i < paper.getNum().size(); i++) {
boolean questionFound = false;
boolean answerProvided = false;
boolean isValidQuestion = false;

        // 查找题目for (Question question : questionlist) {if (paper.getNum().get(i) == question.getNum()) {questionFound = true;if (question.isIstrue()) {isValidQuestion = true;}break;}}// 比较答案for (int x = 0; x < newAnswer.getNumber().size(); x++) {if (i + 1 == newAnswer.getNumber().get(x)) {answerProvided = true;break;}}// 计算分数if (answerProvided && isValidQuestion) {// 正确性判定逻辑...}}
}

}
展开
5. 总分校验
验证试卷总分是否为 100 分:
if (totalScore != 100) {
System.out.println("alert: full score of test paper1 is not 100 points");
}
程序运行逻辑
输入解析:基于正则表达式处理多种输入类型,如题目、试卷、答题记录等。
String pattern = "#N:(\d+) #Q:(.+) #A:(\d+)";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(input);
if (m.find()) {
Question qs = new Question(...); // 创建题目
}
题目与试卷管理:
保存所有题目、试卷的有效信息。
支持通过编号删除题目。
答案对比与得分计算:
将学生答案与标准答案对比。
判定正确、部分正确和错误,分配对应得分。
if (allCorrect && !anyIncorrect) {
studentScore += paper.getScore().get(i);
} else if (correctCount > 0) {
studentScore += paper.getScore().get(i) / 2; // 部分得分
}
结果输出:
输出学生得分。
输出每道题的答题结果。
改进建议
输入验证模块化:
将不同输入类型的正则解析抽取为工具方法,提高复用性。
答题逻辑优化:
增加题目随机生成、打乱顺序的功能,模拟实际考试。
性能优化:
使用哈希表存储题目与答案,加快匹配与比对速度。
序列化支持:
实现题库和答题记录的存储与加载功能,提升系统实用性。

题目二:智能家居强电电路模拟系统
功能需求解析
设备管理:
包含多种设备类型,如开关(SwitchDevice)、调速器(SteppedSpeedController、ContinuousSpeedController)、灯具(WhiteIncandescentLamp、DaylightLamp)、风扇(FanDevice)。
每个设备有独特的属性和行为。
电路模拟:
电路由多个设备串联连接,输入电压通过设备链传递和处理。
设备状态控制:
支持通过命令调整设备状态,如切换开关、调节速度、设置参数等。
输出结果:
模拟电路后输出设备的状态或计算值(如灯的亮度、风扇的速度)。
设计与实现分析
系统设计采用面向对象编程,核心在于抽象设备行为、设备继承关系,以及电路的拓扑管理。

类图
以下是该题目的类图,用于描述设备继承结构和电路管理的关系:

各类与方法介绍

  1. Device 类
    设备的抽象基类,定义了设备的通用属性和行为。

属性:
id:设备唯一标识符。
type:设备类型(如开关、调速器等)。
number:设备编号。
方法:
getOutputVoltage(double inputVoltage):根据输入电压计算输出电压,子类需实现。
2. ControlDevice 类
继承 Device,表示控制设备,用于调节电压或控制设备链的状态。

方法:
toggle():切换设备的状态(如开关开启或关闭)。
2.1 SwitchDevice 类
开关设备,用于控制电路的通断。

属性:
state:开关状态(0 为开通,1 为关闭)。
方法:
getOutputVoltage(double inputVoltage):如果开关关闭,输出电压为输入电压;如果开关开启,输出为 0。
toggle():切换开关状态。
代码示例:

SwitchDevice switchDevice = new SwitchDevice("K1", 1);
switchDevice.toggle(); // 切换状态
System.out.println(switchDevice.getOutputVoltage(220)); // 输出电压
2.2 SteppedSpeedController 类
分档调速器,用于调节电压分级输出。

属性:
currentStep:当前档位(0-3)。
方法:
getOutputVoltage(double inputVoltage):根据当前档位输出比例电压。
increaseStep():提高档位。
decreaseStep():降低档位。
代码示例:

SteppedSpeedController controller = new SteppedSpeedController("F1", 1);
controller.increaseStep(); // 提高档位
System.out.println(controller.getOutputVoltage(220)); // 输出电压
2.3 ContinuousSpeedController 类
连续调速器,用于根据参数比例调节输出电压。

属性:
parameter:调节比例(0.00-1.00)。
方法:
getOutputVoltage(double inputVoltage):按比例输出电压。
setParameter(double newParam):设置新的调节比例。
代码示例:

ContinuousSpeedController continuousController = new ContinuousSpeedController("L1", 1);
continuousController.setParameter(0.5); // 设置比例
System.out.println(continuousController.getOutputVoltage(220)); // 输出电压
3. ControlledDevice 类
继承 Device,表示受控设备,用于模拟响应电压变化的设备状态。

方法:
computeState(double inputVoltage):根据输入电压计算设备状态。
getOutputVoltage(double inputVoltage):受控设备不改变电压,直接输出 0。
3.1 WhiteIncandescentLamp 类
白炽灯设备,亮度根据输入电压计算。

属性:
brightness:灯的亮度(0-200)。
方法:
computeState(double inputVoltage):根据输入电压计算亮度。
getBrightness():返回当前亮度。
3.2 DaylightLamp 类
日光灯设备,亮度为两种状态(0 或 180)。

属性:
brightness:灯的亮度(0 或 180)。
方法:
computeState(double inputVoltage):根据输入电压切换亮度。
3.3 FanDevice 类
风扇设备,转速根据输入电压计算。

属性:
speed:风扇转速(0-360)。
方法:
computeState(double inputVoltage):根据输入电压计算转速。
getSpeed():返回当前转速。
代码示例:

FanDevice fan = new FanDevice("D1", 1);
fan.computeState(100); // 输入电压
System.out.println(fan.getSpeed()); // 输出转速
主类 Main 的解析
主类 Main 是智能家居强电电路模拟系统的核心控制模块,负责以下主要任务:

输入解析与设备链初始化:

解析输入的设备链配置(连接格式)和命令(操作格式)。
创建设备实例并构建电路连接。
电路仿真:

模拟电压从电源(VCC)传递到地(GND)的过程。
通过设备链传递电压并计算各设备状态。
命令执行:

根据用户输入的命令调整设备状态(如切换开关、调节调速器档位或参数)。
输出设备状态:

按设备类型和编号顺序,输出每个设备的状态或计算值。
核心逻辑模块

  1. 数据存储与初始化
    主类初始化时,存储输入数据,并构建设备链及命令列表:

设备链存储:通过 List 动态存储设备实例。
设备映射:通过 Map<String, Device> 存储设备的唯一标识符(如 K1、D2)与设备实例的映射关系,便于快速查询。
命令列表:存储命令行用于状态调整。
代码示例:

List connectionLines = new ArrayList<>();
List commandLines = new ArrayList<>();
Map<String, Device> devicesMap = new HashMap<>();
List deviceChain = new ArrayList<>();
2. 设备链解析
输入的设备链格式(如 [VCC K1-1] [K1-2 D2-1] [D2-2 GND])表示设备的连接关系。

每个连接点由两个端口组成,解析端口并确定设备的输入输出。
根据设备类型和编号创建相应的设备实例(通过 Device 子类)。
按设备连接顺序,依次构建设备链。
代码示例:

for (String conn : connectionLines) {
String content = conn.substring(1, conn.length() - 1).trim();
String[] pins = content.split("\s+");
if (pins.length != 2) continue;

String pinA = pins[0];
String pinB = pins[1];
String deviceId = pinB.split("-")[0];// 根据设备类型创建设备实例
Device device = devicesMap.getOrDefault(deviceId, createDevice(deviceId));
if (device != null && !deviceChain.contains(device)) {deviceChain.add(device);devicesMap.put(deviceId, device);
}

}
辅助方法:

private Device createDevice(String deviceId) {
char type = deviceId.charAt(0); // 获取设备类型(K, F, L, B, R, D)
int number = Integer.parseInt(deviceId.substring(1));

switch (type) {case 'K': return new SwitchDevice(deviceId, number);case 'F': return new SteppedSpeedController(deviceId, number);case 'L': return new ContinuousSpeedController(deviceId, number);case 'B': return new WhiteIncandescentLamp(deviceId, number);case 'R': return new DaylightLamp(deviceId, number);case 'D': return new FanDevice(deviceId, number);default: return null; // 未知设备类型
}

}
3. 命令解析与执行
用户输入的命令控制设备状态(如切换开关、调节调速器档位等)。命令格式包括:

切换开关:#K1 表示切换开关 K1。
调节档位:#F1+ 或 #F1- 表示增加或减少档位。
设置参数:#L1:0.5 表示将调速器 L1 的参数设置为 0.5。
逻辑处理:

遍历命令列表,根据命令类型操作对应设备。
代码示例:

for (String cmd : commandLines) {
if (cmd.startsWith("#K")) { // 切换开关
String deviceId = cmd.substring(1);
Device device = devicesMap.get(deviceId);
if (device instanceof SwitchDevice) {
((SwitchDevice) device).toggle();
}
} else if (cmd.startsWith("#F")) { // 调节分档控制器
String deviceId = cmd.substring(1, cmd.length() - 1);
char operation = cmd.charAt(cmd.length() - 1);
Device device = devicesMap.get(deviceId);
if (device instanceof SteppedSpeedController) {
if (operation == '+') ((SteppedSpeedController) device).increaseStep();
else if (operation == '-') ((SteppedSpeedController) device).decreaseStep();
}
} else if (cmd.startsWith("#L")) { // 设置连续控制器参数
String[] parts = cmd.split("😊;
String deviceId = parts[0].substring(1);
double param = Double.parseDouble(parts[1]);
Device device = devicesMap.get(deviceId);
if (device instanceof ContinuousSpeedController) {
((ContinuousSpeedController) device).setParameter(param);
}
}
}
4. 电路仿真
电路仿真是主类的核心逻辑:

起始电压:从 VCC 开始,初始电压为 220V。
电压传递:通过设备链依次传递电压,并计算各设备状态。
电压终止:到达 GND 后,电压归零。
核心代码:

double currentVoltage = 220.0; // 起始电压
for (Device device : deviceChain) {
if (device instanceof ControlDevice) {
currentVoltage = ((ControlDevice) device).getOutputVoltage(currentVoltage);
} else if (device instanceof ControlledDevice) {
((ControlledDevice) device).computeState(currentVoltage);
currentVoltage = 0.0; // 受控设备后电压归零
}
}
5. 输出设备状态
按设备类型和编号顺序,输出每个设备的状态或计算值。

排序逻辑:先按设备类型排序(K, F, L, B, R, D),再按编号排序。
设备状态:
开关设备:ON 或 OFF。
调速器:当前档位或比例参数。
灯具:亮度值。
风扇:转速值。
代码示例:

List outputDevices = new ArrayList<>(devicesMap.values());
outputDevices.sort((d1, d2) -> {
String typeOrder = "KFLBRD";
int typeCompare = typeOrder.indexOf(d1.type) - typeOrder.indexOf(d2.type);
return typeCompare != 0 ? typeCompare : Integer.compare(d1.number, d2.number);
});

for (Device device : outputDevices) {
System.out.println("@" + device.id + ":" + device.getOutputString());
}
运行流程总结
解析输入:

解析设备连接并生成设备链。
解析命令并存储待执行操作。
执行仿真:

模拟电压传递,逐个设备处理电压并计算状态。
调整状态:

根据命令调整设备行为。
输出结果:

按顺序输出设备状态。
运行逻辑解析
输入解析:
输入设备链连接(如 [VCC K1-1] [K1-2 D1-1] [D1-2 GND]),逐步创建设备并连接。
命令解析(如 #K1 切换开关,#F1+ 增加档位)。
电路模拟:
电压从 VCC 端开始传递,每个设备处理后更新输出电压,直到到达 GND。
结果输出:
输出每个设备的状态或计算值。
改进建议
增加并联电路支持:
支持复杂的并联拓扑结构。
设备扩展性:
新增如智能插座、调光灯等设备类型。
性能优化:
引入缓存机制,避免重复计算状态。

题目三:智能家居系统迭代改进
功能需求解析
本题是对智能家居强电电路模拟系统(题目二)的迭代优化,新增了以下功能和改进:

并联与串联电路的组合:
引入 Circuit 抽象接口,支持串联电路(SerialCircuit)与并联电路(ParallelCircuit)的组合模拟。
模拟复杂电路拓扑结构(如多个支路并联的电路)。
设备工厂模式:
使用 DeviceFactory 动态创建设备实例,简化设备实例化逻辑。
改进的电路模拟:
支持递归地分配电压到并联和串联组件。
提高代码的可读性和扩展性。
命令解析与设备控制优化:
支持更复杂的命令输入,如切换开关、调整调速器档位等。
独立的命令执行模块便于扩展。
类图
以下是本题设计的类图:

类与方法解析

  1. Device 接口
    表示一个设备的通用行为,定义了设备必须实现的两个方法:

方法:
getOutputString():返回设备的状态字符串(如开关状态、灯亮度、风扇转速)。
distributeVoltage(voltage, deviceVoltages):根据输入电压计算设备状态,并将电压分配给后续设备。
2. SwitchDevice 类
开关设备,继承自 Device,用于控制电路的通断。

属性:
isOn:开关状态,true 表示开启,false 表示关闭。
方法:
toggle():切换开关状态。
getOutputString():返回开关状态(如 ON 或 OFF)。
distributeVoltage(voltage, deviceVoltages):
如果开关关闭,则输出电压为 0。
如果开关开启,则传递输入电压。
3. SteppedSpeedController 类
分档调速器,用于分级调节电压。

属性:
step:当前档位(0-3)。
方法:
increaseStep():提高档位。
decreaseStep():降低档位。
getOutputString():返回当前档位。
distributeVoltage(voltage, deviceVoltages):根据档位输出比例电压。
4. ContinuousSpeedController 类
连续调速器,用于按比例调节输出电压。

属性:
parameter:调节比例(0.00-1.00)。
方法:
setParameter(double param):设置比例。
getOutputString():返回当前比例。
distributeVoltage(voltage, deviceVoltages):按比例输出电压。
5. WhiteIncandescentLamp 和 FanDevice 类
分别表示灯具和风扇设备,受输入电压控制。

方法:
computeState(double voltage):根据输入电压计算亮度或转速。
getOutputString():返回亮度或转速值。
distributeVoltage(voltage, deviceVoltages):设备不改变电压,传递 0。
6. Circuit 接口
表示一个电路结构,支持递归的电路拓扑组合。

方法:
addComponent(Circuit component):向电路中添加子组件(设备或子电路)。
distributeVoltage(voltage, deviceVoltages):将输入电压分配到子组件。
7. SerialCircuit 类
串联电路实现。

属性:
components:存储串联的子组件。
方法:
addComponent(Circuit component):添加设备或电路。
distributeVoltage(voltage, deviceVoltages):将输入电压按顺序传递给每个组件。
8. ParallelCircuit 类
并联电路实现。

属性:
branches:存储并联的子电路或设备。
方法:
addComponent(Circuit component):添加设备或电路。
distributeVoltage(voltage, deviceVoltages):将输入电压均分给每个分支。
9. DeviceCircuit 类
用于将单个设备适配为电路组件。

属性:
device:引用一个设备。
方法:
distributeVoltage(voltage, deviceVoltages):分配电压到设备。
addComponent(Circuit component):不支持子组件。
10. DeviceFactory 类
设备工厂,负责动态生成设备实例。

属性:
devicesMap:缓存所有创建的设备,避免重复创建。
方法:
getDevice(String deviceId):根据设备 ID 创建或返回设备实例。
getAllDevices():返回所有已创建的设备。
主类 Main 的核心逻辑
主类负责集成设备与电路管理,主要功能如下:

解析输入:

解析设备链连接(串联和并联)。
使用 DeviceFactory 动态生成设备实例。
构建电路:

将设备与子电路组合为主电路(SerialCircuit 或 ParallelCircuit)。
支持嵌套组合。
处理命令:

执行状态调整命令(切换开关、调节调速器档位等)。
电路仿真与输出:

仿真电路电压传递,输出设备状态。
主类 Main 的解析
主类 Main 是整个智能家居系统的核心控制模块,负责将各个功能模块(如设备创建、电路构建、命令执行、电路仿真等)集成到一起,实现整体逻辑。它的功能主要分为以下几部分:

  1. 输入解析与数据初始化
    解析设备和电路结构
    输入数据中描述了电路结构,分为两部分:

电路连接关系:
输入格式如 [VCC K1-1] [K1-2 D1-1] [D1-2 GND],表示设备及其连接点。
主类解析输入,动态创建设备实例,并通过 SerialCircuit 或 ParallelCircuit 构建完整电路。
实现逻辑:

利用 DeviceFactory 动态创建设备。
根据连接关系,将设备包装成 DeviceCircuit,再添加到对应的 SerialCircuit 或 ParallelCircuit 中。
代码示例:

List connections = Arrays.asList(
"[VCC K1-1]",
"[K1-2 F1-1]",
"[F1-2 D1-1]",
"[D1-2 GND]"
);

Map<String, Device> deviceMap = new HashMap<>();
DeviceFactory deviceFactory = new DeviceFactory();
SerialCircuit mainCircuit = new SerialCircuit();

for (String conn : connections) {
String[] parts = conn.replaceAll("[\[\]]", "").split(" ");
String deviceId = parts[1].split("-")[0];
Device device = deviceFactory.getDevice(deviceId);
if (!deviceMap.containsKey(deviceId)) {
deviceMap.put(deviceId, device);
}
mainCircuit.addComponent(new DeviceCircuit(device));
}
解析命令
命令输入用于控制设备状态,例如:

切换开关:#K1
增加档位:#F1+
调整比例:#L1:0.5
实现逻辑:

逐行读取命令,解析操作类型和目标设备。
根据设备类型调用对应方法调整状态。
代码示例:

List commands = Arrays.asList(
"#K1",
"#F1+",
"#L1:0.5"
);

for (String cmd : commands) {
if (cmd.startsWith("#K")) { // 开关切换
String deviceId = cmd.substring(1);
Device device = deviceMap.get(deviceId);
if (device instanceof SwitchDevice) {
((SwitchDevice) device).toggle();
}
} else if (cmd.startsWith("#F")) { // 调节分档控制器
String deviceId = cmd.substring(1, cmd.length() - 1);
char operation = cmd.charAt(cmd.length() - 1);
Device device = deviceMap.get(deviceId);
if (device instanceof SteppedSpeedController) {
if (operation == '+') ((SteppedSpeedController) device).increaseStep();
else if (operation == '-') ((SteppedSpeedController) device).decreaseStep();
}
} else if (cmd.startsWith("#L")) { // 设置连续控制器参数
String[] parts = cmd.split("😊;
String deviceId = parts[0].substring(1);
double param = Double.parseDouble(parts[1]);
Device device = deviceMap.get(deviceId);
if (device instanceof ContinuousSpeedController) {
((ContinuousSpeedController) device).setParameter(param);
}
}
}
展开
2. 电路仿真
分配电压
电路仿真通过递归分配电压来模拟电路行为:

起始电压:
电源 VCC 的初始电压为 220V。
递归传递:
串联电路:按顺序传递电压。
并联电路:将电压均分给所有分支。
实现逻辑:

调用 SerialCircuit 和 ParallelCircuit 的 distributeVoltage 方法分配电压。
通过 DeviceCircuit 调用设备的 distributeVoltage 方法计算设备状态。
代码示例:

double initialVoltage = 220.0;
Map<Device, Double> deviceVoltages = new HashMap<>();
mainCircuit.distributeVoltage(initialVoltage, deviceVoltages);

// 分配后的设备状态
for (Map.Entry<Device, Double> entry : deviceVoltages.entrySet()) {
Device device = entry.getKey();
double voltage = entry.getValue();
System.out.println("Device: " + device.getOutputString() + " Voltage: " + voltage);
}
设备状态更新
每个设备根据分配到的电压更新自身状态:

开关:判断是否导通。
调速器:根据档位或参数调整输出电压。
灯具/风扇:根据输入电压计算亮度或转速。
示例代码:

for (Device device : deviceMap.values()) {
if (device instanceof ControlledDevice) {
((ControlledDevice) device).computeState(deviceVoltages.get(device));
}
}
3. 输出结果
输出设备状态
按设备类型和编号顺序,输出每个设备的状态。

开关:ON 或 OFF。
调速器:当前档位或比例参数。
灯具:亮度值。
风扇:转速值。
代码示例:

List devices = new ArrayList<>(deviceMap.values());
devices.sort((d1, d2) -> {
String typeOrder = "KFLBRD";
int typeCompare = typeOrder.indexOf(d1.getClass().getSimpleName().charAt(0)) -
typeOrder.indexOf(d2.getClass().getSimpleName().charAt(0));
return typeCompare != 0 ? typeCompare : Integer.compare(d1.getNumber(), d2.getNumber());
});

for (Device device : devices) {
System.out.println("@" + device.getId() + ":" + device.getOutputString());
}
主类 Main 的主要功能总结
输入解析:

构建设备和电路结构,支持串联与并联组合。
动态解析命令,支持灵活的设备控制。
电路仿真:

模拟电压传递和设备状态更新。
支持复杂的电路拓扑结构(递归嵌套)。
结果输出:

输出电路仿真结果,包括设备的电压和状态。
运行逻辑总结
输入解析模块化:支持复杂的并联与串联组合。
设备工厂简化逻辑:通过 DeviceFactory 动态创建设备。
递归仿真电路:支持嵌套的电路拓扑结构。
结果输出清晰:输出
所有设备的状态或结果值。

心得体会

  1. 面向对象设计的重要性
    这三题的核心在于如何使用面向对象设计原则来模拟复杂系统。尤其是设备与电路的建模,体现了以下几方面的价值:

抽象和继承:通过 Device 和 Circuit 的接口设计,实现了对设备和电路行为的抽象。设备的具体实现(如开关、调速器、灯具等)都可以遵循统一接口,便于扩展新设备类型。
组合优于继承:通过组合电路(串联与并联)代替继承,体现了灵活性和模块化的设计思想,便于递归处理复杂电路结构。
设计模式的运用:使用工厂模式 (DeviceFactory) 动态创建设备,解耦了主类与具体设备类型的关系,提高了系统的扩展性。
2. 代码组织与模块化的价值
将代码划分为多个独立模块,每个模块专注于完成一个任务,例如:

输入解析:专注于数据的格式校验与结构构建。
电路模拟:递归处理电压传递,独立封装串联与并联逻辑。
命令执行:单独处理用户命令,灵活扩展。
状态输出:负责统一的状态展示,易于维护。
这种模块化设计,不仅提高了代码的可读性和复用性,也便于后续的功能扩展和维护。

  1. 系统扩展性和灵活性
    这些题目特别强调系统的扩展性:

扩展设备类型:
通过继承 Device 接口,能够轻松添加新的设备类型。
如需新增设备(如智能插座或调光灯),只需实现 distributeVoltage 和 getOutputString 方法。
扩展电路结构:
通过递归定义 Circuit 接口,支持任意复杂的嵌套电路结构。
新增电路类型(如混联电路)也变得相对容易。
扩展命令:
将命令解析与执行分离,便于新增操作逻辑(如远程控制或批量操作)。
4. 面对复杂系统的分步解决思路
三道题逐步增加了系统复杂度,从单一设备管理到递归电路模拟,再到支持并联和嵌套电路,充分体现了解决复杂系统问题的分步思路:

从简单到复杂:逐步增加功能(如从串联电路到并联电路),避免一次性解决所有问题。
分解问题:将复杂的电路问题拆解为子问题(如设备行为、电压分配、状态更新)。
测试驱动开发:每个模块完成后进行独立测试,确保其行为符合预期。
5. 教训与改进空间
教训
输入解析复杂性:
处理复杂的嵌套电路拓扑时,输入解析容易变得臃肿,正则表达式或字符串解析代码显得复杂。应该考虑引入更清晰的数据结构来描述输入格式。
性能优化:
如果设备数量或电路嵌套层次较多,递归仿真的性能可能成为瓶颈。可以考虑优化电压传递的算法或引入缓存机制。
错误处理:
系统对输入错误的容错能力需要加强,比如当命令中设备不存在或电路中连接有误时,应该给出更清晰的错误提示。
改进空间
输入解析改进:
可以采用 JSON 或 XML 格式作为输入结构,便于描述复杂的电路关系,同时简化解析逻辑。
测试覆盖:
增加单元测试和集成测试,覆盖更多的边界条件(如异常输入、电路短路、设备断电等)。
用户友好性:
提供更人性化的命令行界面(CLI)或图形用户界面(GUI),让用户能够直观地构建和模拟电路。
总结
这三道题目不仅是对面向对象设计和编程能力的考验,也是对解决复杂系统问题思维的锻炼。它让我深刻体会到:

分步解决问题的力量:通过逐步完善系统功能,可以有效降低复杂性。
面向对象设计的灵活性:良好的抽象设计让系统具备高度的扩展性和可维护性。
细节与整体的平衡:既要关注系统整体架构,也要注重每个模块的实现细节。
通过这次练习,我不仅巩固了面向对象设计的核心思想,还加深了对工程化开发方法的理解。这将对今后的开发工作提供宝贵的经验和参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/840352.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第九周学习总结

学期2024-2025-1 学号20241414 《计算机基础与程序设计》第九周学习总结 作业信息这个作业属于哪个课程 <班级的链接>2024-2025-1-计算机基础与程序设计这个作业要求在哪里 <作业要求的链接>2024-2025-1计算机基础与程序设计第九周作业这个作业的目标 操作系统责任…

k8s阶段03 持久卷, PV和PVC, CSI存储方案示例csi-driver-nfs, OpenEBS, ConfigMap, Secret, DownwardAPI和Projected

2持久卷 PV和PVC在Pod级别定义存储卷有两个弊端卷对象的生命周期无法独立于Pod而存在用户必须要足够熟悉可用的存储及其详情才能在Pod上配置和使用卷PV和PVC可用于降低这种耦合关系PV(Persistent Volume)是集群级别的资源,负责将存储空间引入到集群中,通常由管理员定义PVC(…

iOS 审核被拒记录 2.5.1

解决方案一(当前项目不需要HealthKit框架,将HealthKit相关内容和权限移除)解决方案二(当前项目需要HealthKit框架)Guideline 2.5.1 - Performance - Software RequirementsYour apps binary includes references to HealthKit components, but the app does not appear to …

20241313 刘鸣宇 《计算机基础与程序设计》第九周学习总结

2024-2025-1 20241313 刘鸣宇 《计算机基础与程序设计》第九周学习总结 作业信息这个作业属于哪个课程 <班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>(如2024-2025-1计算机基础与程序设计第一周作业)这个作业的目标 <…

MySQL原理简介—4.深入分析Buffer Pool

大纲 1.Buffer Pool是什么 2.如何配置Buffer Pool的大小 3.数据页是MySQL中抽象出来的数据单位 4.数据页如何对应Buffer Pool中的缓存页 5.缓存页对应的描述信息是什么 6.Buffer Pool简单总结 7.数据库启动时如何初始化Buffer Pool 8.free链表可判断哪些缓存页是空闲的 9.free链…

MySQL原理简介—2.InnoDB架构原理和执行流程

大纲 1.更新语句在MySQL中是如何执行的 2.重要的内存结构—Buffer Pool缓冲池 3.undo日志文件如何让更新的数据可以回滚 4.更新Buffer Pool缓冲池中的缓存数据 5.Redo Log Buffer如何避免宕机时数据丢失 6.如果还没提交事务时MySQL宕机了怎么办 7.提交事务时将redo日志写入磁盘…

【Azure 环境】从网络包中分析出TLS加密套件信息

An TLS 1.2 connection request was received from a remote client application, but non of the cipher suites supported by the client application are supported by the server. The connection request has failed.从远程客户端应用程序收到 TLS 1.2 连接请求,但服务器…

TCP可靠机制详解

重传机制 针对数据包丢失的情况,会用重传机制解决。 超时重传 在发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的ACK 确认应答报文,就会重发该数据,也就是我们常说的超时重传。TCP 会在以下两种情况发生超时重传:数据包丢失,确认应答丢失 缺点:当超时时…

记一次uniapp安卓原生插件升级

本来七月份就想升级来自,也是碰到了这个问题,能看出来是java版本不对,但就是不知道哪里忘了改,直到昨天emmm

实验4 类的组成、继承、模板类、标准库

任务二: 代码: task2.cpp:1 #include "GradeCalc.hpp"2 #include <iomanip>3 4 void test() {5 int n;6 cout << "输入班级人数: ";7 cin >> n;8 9 GradeCalc c1("OOP", n); 10 11 cout << &quo…

Fanatastic pg walkthrough 10 Easy

nmap 发现9090 22 和3000端口发现漏洞但是不知道还能读到哪些敏感文件 hacktricks 看看 https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/grafana 通过hacktricks告诉我们的两个文件 发现secret key SW2YcwTIb9zpOOhoPsMm 发现basic密码 {"basi…

VMware App Volumes 4, version 2410 (4.15) - 实时应用程序交付系统

VMware App Volumes 4, version 2410 (4.15) - 实时应用程序交付系统VMware App Volumes 4, version 2410 (4.15) - 实时应用程序交付系统 重新定义跨 VDI、DaaS 和已发布的应用环境交付和管理应用的方式 请访问原文链接:https://sysin.org/blog/vmware-app-volumes/ 查看最新…