22207321-王郅坚-BLOG2

news/2025/2/26 22:07:27/文章来源:https://www.cnblogs.com/Vvzz/p/18564746

前言
这三次题目集涉及了不同的知识点、编程技巧及而算法逻辑,从简单的基础题目逐步过渡到复杂的业务逻辑模拟。三次题目集不仅是单单考核独立的编程任务,其实它们有明确的迭代关系,逐步递进并且不断添加复杂度。题目集1是针对前三次的题目再进行迭代升级,题目集2开始了一个新的题目类型,并在题目三中进行迭代升级。通过这三次作业,编程能力从基础的算法实现提升到具备一定的系统化设计能力,同时也逐步强化代码的复用性、健壮性和扩展性。在题目集1到题目集3的迭代过程中,我体会到了代码结构设计的重要性。这不仅仅是从各个模块功能的角度来实现,还要考虑代码的可读性、可维护性,甚至整个系统的扩展性。在每一次的迭代中,代码的模块化设计增强了系统的灵活性,而面向对象的设计思想让不同的模块解耦,使复杂的逻辑变得更容易应对。

题目集一-复杂的答题系统设计

  1. 功能设计
    该代码实现了一个简单的考试系统,具备以下核心功能:
  • 题目管理:

    • 支持单选题、多选题和填空题。
    • 问题可以被标记为已删除,不再参与评分。
  • 试卷管理:

    • 每张试卷可以包含多个问题及对应分数,并计算总分。
  • 答卷管理:

    • 学生可以提交答卷,系统可以自动评判答案的正确性,并显示结果。
  • 输入处理:

    • 从标准输入读取特定格式的题目、试卷和答卷数据。
  • 结果显示:

    • 显示每位学生的答卷结果,包括题目内容、学生答案、评分情况和总分。
  1. 代码结构分析
  • 类设计:

    • Question(抽象类)及其子类(SingleChoiceQuestion, MultipleChoiceQuestion, FillInTheBlankQuestion)用于抽象和实现不同题型的共性。
    • TestPaper用于管理与试卷相关的功能。
    • AnswerSheet用于存储和管理学生的答卷信息。
    • Main类用于处理输入、解析数据、管理试卷与答卷,并最终输出结果。
  • 数据结构:

    • 使用ListMap存储题目、试卷和学生数据,便于动态管理和快速查找。
  1. 时间复杂度分析
  • 读取输入时,解析每行数据的时间复杂度是 O(n),其中 n 是输入行数。

  • compareAnswer方法的复杂度因题型而异:

    • 对于单选题、填空题复杂度为 O(m),其中 m 为答案的字符串长度。
    • 对于多选题复杂度为 O(p + q),其中 p 和 q 分别为正确选项和学生选项的数目(在处理集合时所用的保留操作中,通常保持列表的大小)。
  • 总体操作如下:

    • 处理输入:O(n)
    • 处理每个AnswerSheet.displayResults():O(k)(k 为题目数)
  1. 空间复杂度分析
  • questions, testPapers, answerSheets的空间复杂度各为 O(q + t + a),其中 q 为题目数量,t 为试卷数量,a 为答卷数量。
  • 使用Map缓存题目的空间复杂度为 O(q),对应每个题目的存储。
  1. 圈复杂度分析
  • 圈复杂度较低,大多数方法只有if和for循环,圈复杂度通常在 1 到 3 之间,逻辑清晰。
  • 处理答题结果的代码通过条件判断来评估答案的正确性,圈复杂度在合理范围,不易产生复杂的逻辑分支。
  1. 代码分析

  2. 题目管理

目的
题目管理的目的是支持创建和管理不同类型的题目(单选题、多选题和填空题),可以添加、删除题目,并进行答案比较。

实现

  • 类设计:
    • 抽象类 Question 定义了通用的题目属性和行为,如题目编号、内容、标准答案及删除状态。
    • 其子类 SingleChoiceQuestionMultipleChoiceQuestionFillInTheBlankQuestion 实现了针对不同题型的特定比较逻辑。
abstract class Question {protected int numOfQuestion;protected String contentQuestion;protected String standardAnswer;protected boolean isDeleted = false;public abstract String compareAnswer(String answer);
}
  • 子类实现:
    • 每个子类都重写了 compareAnswer 方法,用于比较学生的答案与标准答案,如下:
class SingleChoiceQuestion extends Question {@Overridepublic String compareAnswer(String answer) {if (answer != null && answer.trim().equalsIgnoreCase(standardAnswer.trim())) {return "true"; // 答案正确}return "false"; // 答案错误}
}class MultipleChoiceQuestion extends Question {@Overridepublic String compareAnswer(String answer) {// 对答案的逻辑实现,略,具体逻辑包括处理部分正确等}
}

关键逻辑

  • 使用 equalsIgnoreCase 用于单选题的答案比较,使得比较不区分大小写。
  • 对于多选题,使用 retainAll 方法处理部分正确性,使得答案比较灵活。
  1. 试卷管理

目的
试卷管理的功能是允许教师创建并管理试卷,包含题目的组织和相关分数的管理,以便最终换算总分。

实现

  • 类设计:
    • TestPaper 类用于存储试卷信息,包含试卷编号及对应的问题和分数列表。
class TestPaper {private int testPaperId;private List<Question> questions = new LinkedList<>();private List<Integer> scores = new LinkedList<>();public void addQuestion(Question question, int score) {questions.add(question);scores.add(score); // 记录分数}public int getTotalScore() {return scores.stream().mapToInt(Integer::intValue).sum(); // 计算总分}
}

关键逻辑

  • 通过 addQuestion 方法动态添加题目和分数,构建试卷。
  • 使用流(stream)计算总分,体现了Java 8的特性,便于实现高效计算。
  1. 答卷管理

目的
答卷管理的功能是允许学生提交答案并提供结果反馈,包括每道题的得分和总分。

实现

  • 类设计:
    • AnswerSheet 类用于存储学生答案、关联的试卷以及最终显示结果。
class AnswerSheet {private TestPaper testPaper;private List<String> answers = new LinkedList<>();public void displayResults() {StringBuilder resultBuilder = new StringBuilder();int totalScore = 0;for (int i = 0; i < testPaper.getQuestions().size(); i++) {Question question = testPaper.getQuestions().get(i);String answer = answers.size() > i ? answers.get(i) : null; // 获取答案String correctness = question.compareAnswer(answer);int score = "true".equals(correctness) ? testPaper.getScores().get(i) : 0; // 评分totalScore += score;resultBuilder.append(question.getContentQuestion()).append("~").append(answer).append("~").append(correctness).append("\n"); // 输出格式}System.out.print(resultBuilder.toString()); // 打印结果}
}

关键逻辑

  • 使用 StringBuilder 高效构建结果输出,循环遍历试卷的每题,判断学生答案的正确性,计算得分。
  1. 输入处理

目的
输入处理功能负责接收并解析用户输入数据,根据不同类型的问题更新系统的题库、试卷和学生的答卷。

实现

  • 方法设计:
    • 通过 processInput 方法监控输入,根据特定的前缀调用对应处理方法。
private static void processInput(Scanner scanner) {String line;while (!(line = scanner.nextLine()).equals("end")) {if (line.startsWith("#N:")) {processSingleChoiceQuestion(line); // 处理单选题} else if (line.startsWith("#Z:")) {processMultipleChoiceQuestion(line); // 处理多选题} else if (line.startsWith("#K:")) {processFillInTheBlankQuestion(line); // 处理填空题} // 其他处理...}
}

关键逻辑

  • 使用前缀识别输入类型,并调用相应处理逻辑,确保系统能够灵活应对不同输入。
  • 处理格式错误,通过错误列表集中记录并在输出末尾显示,确保用户得到反馈。
  1. 结果显示

目的
结果显示功能用于输出每位学生的得分和相关信息,包括每题的参考答案和得分情况。

实现

  • 方法设计:
    • displayResults 方法负责对每位学生的结果进行格式化输出。
private static void displayResults() {for (AnswerSheet answerSheet : answerSheets) {answerSheet.displayResults(); // 调用答卷显示结果}
}

关键逻辑

  • 将所有答卷排序和格式化后调用显示方法,使得最终输出结果清晰易读。

总结
整体而言,该系统的核心功能设计合理,模块化程度高,各个功能相对独立,便于维护和扩展。题目管理和试卷管理结构清晰,利用面向对象的特点有效管理逻辑。输入处理和结果显示方面通过规范化处理提高用户交互体验。综合而言,这是一种良好的编程实践,能够适应基本的考试系统需求。
以下是题目一的类图,展示了我的代码是如何设计类以及方法的使用:

再是我的顺序图在这个顺序图中,我们展示了以下步骤:

题目集二-基础家居电路的设计

  1. 功能设计

目的
该代码实现了一个电路设备模拟系统,包括多种电气设备的建模和控制,具备处理串联与并联电路的能力,以及输出设备状态的功能。

核心功能

  • 设备建模:使用继承和多态设计了多种电路设备,包括开关、调速器、灯具等。
  • 电路连接:能够处理串联和并联电路,确保设备之间正确传递电压和电流。
  • 设备状态管理:提供设备状态查询功能,并按顺序输出所有设备的状态信息。
  • 用户交互:支持从标准输入读取构建电路的命令,允许用户动态添加设备和电路。
  1. 代码结构分析

类和继承结构

  • 基类:

    • CircuitDevice: 抽象基类,定义了所有电路设备的通用属性和方法(例如 getId()getStatus())。
  • 控制设备:

    • ControlDevice: 继承 CircuitDevice 的抽象类,定义了控制设备共同的功能,如设置输入电压和获取输出电压。
  • 具体设备:

    • Switch, StepRegulator, ContinuousRegulator: 表示具体的控制设备,继承自 ControlDevice 并重写相关方法。
    • ControlledDevice: 另一组设备基类,提供了接受电压差的能力。
    • IncandescentLamp, FluorescentLamp, CeilingFan, FloorFan: 具体的受控设备,重写 getStatus() 方法,返回基于电压差的状态。

方法划分

  • 主要逻辑在 Main 类中,包含输入处理、设备创建、设备控制、和状态显示等方法,模块划分清晰。
  1. 时间复杂度分析
  • 设备创建:parseAndCreateDevice 方法解析字符串并创建设备的复杂度为 O(n),n 为设备数量。
  • 命令处理:每个控制命令的处理(如 processControlCommand)的复杂度为 O(1)。
  • 电路设置:setupCircuit 方法处理串联和并联电路的复杂度为 O(m * p),m 为串联电路的数量,p 为每个串联电路中的设备数量,可能会因为并联电路的搜索而增加复杂度。
  • 状态显示:displayStatus 方法的复杂度为 O(k log k),其中 k 为设备数量,因为排序过程需要 O(k log k) 的时间。
  1. 空间复杂度分析
  • 设备存储:使用 HashMap<String, CircuitDevice> 来存储设备,空间复杂度为 O(n),n 为设备数量。
  • 状态信息存储:在 displayStatus 方法中,需要额外的空间来存储状态字符串,空间复杂度为 O(k),k 为设备数量。
  • 连接数据:串联和并联连接的数据存储空间为 O(p + q),p 为串联连接数量,q 为并联连接数量。
  1. 圈复杂度分析
  • 圈复杂度主要与条件分支和循环有关:
    • 各个控制命令和过程中的 if 语句语句使得圈复杂度添加了1-2。
    • 例如,processControlCommand 方法通过多个 if-else 结构来处理不同的设备控制命令,其圈复杂度为 O(1)。
    • setupCircuit 中包含的双层循环和条件分支会导致圈复杂度上升,但总体上仍能够保持在 O(1-2) 的可接受范围内。

好的,我们将针对您提供的电路设备模拟代码的主要功能进行详细的代码分析。我们将逐个功能模块进行深入分析,包括设备模型的创建、输入处理、电路连接和状态显示。

6.代码分析

  1. 设备模型的创建

功能描述
各个设备通过继承抽象类CircuitDeviceControlDevice以及实现各自的具体逻辑来模拟电路设备的行为。

代码实现

abstract class CircuitDevice {protected String id; // 设备ID// 构造函数public CircuitDevice(String id) {this.id = id;}public String getId() {return id;}public abstract String getStatus(); // 抽象方法,返回设备状态
}
  • 分析
    • CircuitDevice 类是所有电路设备的基类,其构造函数接受设备ID,并提供获取ID的方法。
    • 该类还定义了一个抽象方法 getStatus(),用于返回设备状态的字符串表示。

具体设备实现

class Switch extends ControlDevice {private boolean isClosed; // 开关状态public Switch(String id) {super(id);this.isClosed = false; // 默认状态为打开}public void toggle() {this.isClosed = !this.isClosed; // 切换开关状态}@Overridepublic double getOutputVoltage() {return isClosed ? inputVoltage : 0; // 根据开关状态返回输出电压}@Overridepublic String getStatus() {return "@K" + id + ":" + (isClosed ? "closed" : "turned on");}
}
  • 分析
    • Switch 类从 ControlDevice 继承,包含一个布尔值 isClosed 表示开关是否闭合。
    • 提供 toggle() 方法用于切换开关状态。
    • getOutputVoltage() 方法根据开关状态返回相应的输出电压。
    • getStatus() 方法返回开关状态的字符串表示。
  1. 输入处理

功能描述
负责从用户输入指令获取设备关键信息,创建设备实例并记录电路连接关系。

代码实现

private static void processInput() {Scanner scanner = new Scanner(System.in);boolean end = false;while (!end) {String line = scanner.nextLine().trim();if (line.equals("end")) {end = true; // 结束输入} else if (line.startsWith("#T")) {processSeriesCircuit(line); // 处理串联电路} else if (line.startsWith("#M")) {processParallelCircuit(line); // 处理并联电路} else if (line.startsWith("#")) {processControlCommand(line); // 处理控制命令} else {parseAndCreateDevice(line); // 解析并创建设备}}scanner.close(); // 关闭扫描器
}
  • 分析:
    • processInput 方法在循环中读取用户输入,根据不同的前缀调用不同的处理方法。
    • 处理完毕后关闭输入流,确保资源得到正确释放。

设备解析和创建设备

private static void parseAndCreateDevice(String connection) {String[] pins = connection.replaceAll("[\\[\\]]", "").split(" ");for (String pin : pins) {String[] parts = pin.split("-");String deviceKey = parts[0];// 检查是否需要创建新设备if (!deviceKey.equals("VCC") && !deviceKey.equals("GND") && !devices.containsKey(deviceKey)) {createDevice(deviceKey); // 创建设备}}
}
  • 分析:
    • 该方法解析连接字符串,去掉方括号并分割出设备标识符。
    • 检查标识符是否已存在于 devices 中,如果不存在且不是电源标识符,则调用 createDevice 方法进行创建设备。

创建设备

private static void createDevice(String deviceKey) {char type = deviceKey.charAt(0); // 获取设备类型String id = deviceKey.substring(1); // 获取设备编号switch (type) {case 'K':devices.put(deviceKey, new Switch(id));break;case 'F':devices.put(deviceKey, new StepRegulator(id));break;// 处理其他类型的设备// ...default:break;}
}
  • 分析:
    • 根据设备的类型字符(如 K 表示开关)来创建对应的设备对象,并将其存储在 devices 映射中。
  1. 电路设置

功能描述
根据输入的电路连接信息设置串联和并联电路,确保各个设备能正确地进行电压和电流的交换。

代码实现

private static void setupCircuit() {// 处理串联电路for (String seriesConnection : seriesConnections) {String[] parts = seriesConnection.split(":", 2);String connectionData = parts[1].trim();String[] connections = connectionData.split(" ");double lastOutputVoltage = 0;for (String conn : connections) {// 处理每个连接// 设置电压...}}// 处理并联电路for (String parallelConnection : parallelConnections) {// 类似处理并联电路连接}
}
  • 分析:
    • setupCircuit 方法分两部分处理串联和并联电路。
    • 串联电路中,逐个设备获取并传递电压;并联电路中,确保所有设备共享某一输入电压。
    • 需要确保每个设备在电路中都能获取正确的电压,以便其状态计算。
  1. 状态显示

功能描述
输出所有设备的当前状态,包括根据电压差和电压情况科学计算出的状态值。

代码实现

private static void displayStatus() {List<CircuitDevice> sortedDevices = new ArrayList<>(devices.values());sortedDevices.sort(Comparator.comparing(CircuitDevice::getId));List<String> statuses = new ArrayList<>();for (CircuitDevice device : sortedDevices) {statuses.add(device.getStatus()); // 获取状态字符串}statuses.sort((s1, s2) -> {// 对状态字符串进行排序return Integer.compare(Integer.parseInt(s1.substring(2)), Integer.parseInt(s2.substring(2)));});// 输出状态for (int i = 0; i < statuses.size(); i++) {if (i > 0) {System.out.println();  // 在每行前输出换行符}System.out.print(statuses.get(i));}
}
  • 分析:
    • displayStatus 方法首先对设备按ID排序,然后获取各设备的状态字符串。
    • 进行第二次排序,确保输出顺序符合预定逻辑。
    • 最后,将状态信息输出到控制台,使用适当的格式来避免多余的换行。

总结

上述分析覆盖了代码的主要功能,包括设备的建模、输入的处理、电路的设置和设备状态的显示。每个功能模块均进行了详细的代码实现分析,包括方法的功能、参数、返回值以及潜在的影响。整体代码结构良好,具备良好的可读性以及相对清晰的逻辑分层,适合进行后续的维护和扩展。

如果进一步想要优化该系统,可以考虑如下几点:

  • 增加更多的错误处理,确保无论是设备创建还是电路设置过程中都能安全稳健地应对异常和无效输入。
  • 考虑将电路连接的逻辑进一步简化,可能使用设计模式(如状态模式、责任链模式等)来增加可扩展性。
  • 提升用户体验,比如提供更丰富的输入提示或状态信息,使得操作更加友好。

以下是题目二的类图,展示了我的代码是如何设计类以及方法的使用:

再是我的顺序图在这个顺序图中,我们展示了以下步骤:

题目集三-升级的家居电路设计

  1. 功能设计

目的
该代码实现了一个电路设备模拟系统,可以管理多种电气设备,支持串联和并联电路的设置,以及实时获取设备状态。

核心功能

  • 设备建模:通过抽象类和子类设计,定义了不同类型的电气设备,包括开关、调速器和灯具。
  • 电路连接管理:支持串联与并联电路,能够根据连接关系设定输入和输出电压。
  • 状态管理:可获取各个设备的状态信息,并以特定格式输出。
  • 用户输入处理:从标准输入中读取电子设备的参数和命令,构建电路系统。
  1. 代码结构分析

类和继承结构

  • 基类:

    • CircuitDevice:所有电路设备的基类,定义了设备ID和状态查询方法。
  • 控制设备:

    • ControlDevice(继承自 CircuitDevice):表示可控设备,包含输入电压属性和计算输出电压的方法。
  • 具体设备:

    • SwitchStepRegulatorContinuousRegulator:不同类型的控制设备,如开关和调速器,均继承于 ControlDevice
    • ControlledDevice(继承自 CircuitDevice):受电压影响的设备。
    • IncandescentLampFluorescentLampCeilingFanFloorFan:具体的受控设备,均继承自 ControlledDevice,并实现根据电压差计算亮度或转速的逻辑。

方法划分

  • 实现了清晰的功能划分,主要的功能均在 Main 类中实现,包括输入处理、设备创建、命令处理和状态输出。
  1. 时间复杂度分析
  • 设备创建:parseAndCreateDevice 方法解析设备并创建设备的时间复杂度为 O(n),其中 n 是设备数量。
  • 命令处理:processControlCommand 等处理命令的方法时间复杂度均为 O(1)。
  • 电路设置:setupCircuit 方法的复杂度为 O(m * p),其中 m 为串联电路的数量,p 为每个串联电路中的设备数量。处理并联电路时也同样复杂度。
  • 状态显示:displayStatus 方法的复杂度为 O(k log k),k 为设备数量,因为需要排序。
  1. 空间复杂度分析
  • 设备存储:HashMap<String, CircuitDevice> 用于存储设备,空间复杂度为 O(n),n 为设备数量。
  • 连接信息:串联和并联连接的数据结构分别使用 ArrayList<String> 存储,空间复杂度各为 O(p + q),其中 p 为串联电路数量,q 为并联电路数量。
  1. 圈复杂度分析
  • 圈复杂度:主要由条件分支和循环控制
    • processControlCommand 消息处理涉及多个分支条件,其圈复杂度为 O(1)。
    • setupCircuit 中存在嵌套循环和条件判断,其圈复杂度较高,但仍在 O(n) 范围内,具体取决于循环体内的条件分支数量。
  1. 代码分析

  2. 设备创建

功能描述
设备创建的功能是通过用户输入的标识符创建设备实例,并将其存入设备管理的集合中。该过程不仅有助于初始化设备,还能在构建电路时提供必要的信息。

代码实现

private static void parseAndCreateDevice(String connection) {String[] pins = connection.replaceAll("[\\[\\]]", "").split(" ");for (String pin : pins) {String[] parts = pin.split("-");String deviceKey = parts[0];if (!deviceKey.equals("VCC") && !deviceKey.equals("GND") && !devices.containsKey(deviceKey)) {createDevice(deviceKey);}}
}
  • 分析:
    • 该方法会先去除输入连接字符串中的方括号(如果有),然后将其按空格分割成多个标识符。
    • 遍历每个标识符,利用 split("-") 方法将设备标识符和参数分开。deviceKey 是设备的标识符。
    • 确保不处理虚拟电源设备(VCCGND)以及已存在的设备,只有新的设备会被创建。

设备创建

private static void createDevice(String deviceKey) {char type = deviceKey.charAt(0);String id = deviceKey.substring(1);switch (type) {case 'K':devices.put(deviceKey, new Switch(id));break; // 创建开关设备case 'F':devices.put(deviceKey, new StepRegulator(id));break; // 创建分档调速器case 'L':devices.put(deviceKey, new ContinuousRegulator(id));break; // 创建连续调速器case 'B':devices.put(deviceKey, new IncandescentLamp(id));break; // 创建白炽灯case 'R':devices.put(deviceKey, new FluorescentLamp(id));break; // 创建日光灯case 'D':devices.put(deviceKey, new CeilingFan(id));break; // 创建吊扇case 'A':devices.put(deviceKey, new FloorFan(id));break; // 创建落地扇default:break; // 无识别设备}
}
  • 分析:
    • createDevice 方法根据设备标识符的前缀确定设备类型并实例化适当的对象。每个设备对象都被保存在 devices HashMap 中,key 为设备的标识符,value 为设备实例。
    • 这种结构设计支持很好的扩展性,新设备类型只需新增一个 case 分支即可。
  1. 输入处理

功能描述
该模块负责实时读取用户输入,并根据不同的输入类别调用相应的处理方法。

代码实现

private static void processInput() {Scanner scanner = new Scanner(System.in);boolean end = false;while (!end) {String line = scanner.nextLine().trim(); // 读取输入if (line.equals("end")) {end = true; // 结束输入} else if (line.startsWith("#T")) {processSeriesCircuit(line); // 处理串联电路} else if (line.startsWith("#M")) {processParallelCircuit(line); // 处理并联电路} else if (line.startsWith("#")) {processControlCommand(line); // 处理控制命令} else {parseAndCreateDevice(line); // 解析并创建设备}}scanner.close(); // 关闭扫描器
}
  • 分析:
    • processInput 方法通过一个循环不断读取用户输入。当用户输入 "end" 时,循环停止。
    • 根据输入字符串前缀不同(如 #T#M),分别调用处理串联和并联电路的相关方法。
    • 如果输入的是设备标识符(没有带#),则调用 parseAndCreateDevice 创建设备。这为用户交互提供了良好的灵活性。
  1. 电路设置

功能描述
电路设置部分负责配置设备之间的电气连通,确保正确传递电压和电流。

代码实现

private static void setupCircuit() {for (String seriesConnection : seriesConnections) {String[] parts = seriesConnection.split(":", 2);String connectionData = parts[1].trim();String[] connections = connectionData.split(" ");double lastOutputVoltage = 0; // 上一个设备的输出电压for (String conn : connections) {conn = conn.trim();if (conn.startsWith("[") && conn.endsWith("]")) {conn = conn.substring(1, conn.length() - 1).trim(); // 去掉方括号}String[] elements = conn.split(" "); // 设备和引脚信息String deviceKey = elements[0]; // 获取设备标识符if (elements.length > 1) { // 确保有足够的元素int pinNumber = Integer.parseInt(elements[1].split("-")[1]); // 获取引脚号CircuitDevice device = devices.get(deviceKey);if (pinNumber == 1) { // 输入引脚lastOutputVoltage = (device instanceof ControlDevice) ? ((ControlDevice) device).getOutputVoltage() : 0; // 获取电压} else if (pinNumber == 2) { // 输出引脚if (device instanceof ControlDevice) {((ControlDevice) device).setInputVoltage(lastOutputVoltage); // 设置输入电压} else if (device instanceof ControlledDevice) {((ControlledDevice) device).setVoltageDifference(lastOutputVoltage); // 设置受控设备的电压差}}}}}// 处理并联电路的代码省略...
}
  • 分析:
    • setupCircuit 方法中,首先从串联连接列表中提取每一条连接信息,随后根据设备标识符获取对应的设备实例。
    • 根据引脚号不同,决定是设置输入电压还是电压差。
    • lastOutputVoltage 变量用于保存最近一个设备的输出电压,确保在串联中按正确信息传递电压。
  1. 状态显示

功能描述
负责输出所有设备当前的状态,包括电压、亮度或速度等信息。

代码实现

private static void displayStatus() {List<CircuitDevice> sortedDevices = new ArrayList<>(devices.values());sortedDevices.sort(Comparator.comparing(CircuitDevice::getId));List<String> statuses = new ArrayList<>();for (CircuitDevice device : sortedDevices) {statuses.add(device.getStatus()); // 获取设备状态}statuses.sort((s1, s2) -> {char type1 = s1.charAt(1);char type2 = s2.charAt(1);int order1 = getOrder(type1);int order2 = getOrder(type2);if (order1 != order2) {return Integer.compare(order1, order2);}return Integer.compare(Integer.parseInt(s1.substring(2)), Integer.parseInt(s2.substring(2)));});for (int i = 0; i < statuses.size(); i++) {if (i > 0) {System.out.println(); // 输出换行}System.out.print(statuses.get(i)); // 打印设备状态}
}
  • 分析:
    • displayStatus 获取所有设备的状态字符串,首先将设备按ID排序,然后进一步排序根据设备类型和标识符顺序输出。
    • 使用 getOrder 方法为设备类型制定了固定的排序规则,从而确保输出有序且清晰,便于用户查看。

总结

从以上分析可以看出,该电路设备模拟系统代码结构清晰,功能模块分明。各部分代码实现了明确的逻辑,尽可能考虑了用户输入的灵活性与电路连接的复杂性。特别是在设备创建和状态显示方面,采用了良好的封装和多态特性,使得代码具有较好的可维护性和扩展性。

改进的方面可能包括:

  • 增加对无效输入的处理,尤其是在设备创建和连接设置时,以增强系统的健壮性。
  • 优化电路设置中串联和并联的代码,使其更加模块化,易于维护和扩展。
  • 可以将一些常用的数值或文字定义为常量,例如电压阈值,以增强代码的可读性和可靠性。

以下是题目三的类图,展示了我的代码是如何设计类以及方法的使用:

再是我的顺序图在这个顺序图中,我们展示了以下步骤:

总结

在这三次编程任务中,围绕电子设备的模拟系统进行了设计和实现。每个任务的设计不仅考察了基础编程能力,还逐步引入了复杂的业务逻辑和系统设计理念。

任务一:复杂的答题系统设计

  • 功能设计

    • 该系统实现了题目管理、试卷管理、答卷管理、输入处理和结果显示等核心功能,涵盖了动态管理题目、维护学生答卷并评分等能力。
  • 代码结构分析

    • 采用了面向对象的设计,使用抽象类和继承的方式定义了题目、试卷和答卷等模块,解耦了不同功能的实现。

任务二:基础家居电路的设计

  • 功能设计

    • 实现了电路设备的建模,支持设备状态查询和电路连接的管理,允许用户通过命令动态配置电路。
  • 代码结构分析

    • 进一步利用面向对象的设计原则,定义了电气设备及其层次关系,使用集合类有效管理设备与连接信息。

任务三:升级的家居电路设计

  • 功能设计

    • 在基础电路模拟的基础上扩展了功能,通过命令行输入创建电路、管理设备以及输出状态。
  • 代码结构分析

    • 将输入处理与电路设置逻辑进行清晰的分离,增强了系统的可读性和可维护性。

总体质量分析

1. 可读性与可维护性

  • 结构清晰:三次任务的代码都采用了良好的模块化设计,具备清晰的类结构和方法划分,使得整体代码的可读性较高。
  • 命名规范:类名和方法名表达清晰,反映其功能,便于阅读者理解代码的意图。

2. 错误处理

  • 不足之处:在用户输入和设备创建过程中,错误处理和异常管理较弱,未充分处理非法输入情况,可能导致程序运行失败。
  • 建议:引入适当的输入验证和异常处理机制,以提升用户体验和系统的健壮性。

3. 性能与效率

  • 性能接受:对于中小规模电路和答题任务,系统的时间和空间复杂度均在可接受范畴内,但在处理大量设备和组件的场景中可能会面临性能瓶颈。
  • 建议:考虑使用更高效的数据结构或算法,尤其是在电路设置和设备查询等操作中,可能需引入缓存机制以减少重复计算和查询。

反思与后续提升点

1. 完善输入验证与异常处理

  • 提升建议
    • 对于所有用户输入,增加格式验证与合法性检查,避免因无效输入导致程序崩溃。
    • 在创建设备和设置电路时考虑引入自定义异常处理,确保系统能够在遇到错误时安全而优雅地恢复。

2. 加强测试和文档化

  • 提升建议
    • 针对各个模块增加单元测试覆盖,确保功能实现正确,增强代码的可靠性。
    • 提供详细的 API 文档和使用说明,描述类接口、方法功能及参数,让后续开发者能快速上手。

3. 代码质量改进

  • 提升建议
    • 在设备创建时采用设计模式,如工厂模式,减少复杂度并提升可扩展性。
    • 将重复代码抽出为工具方法,增强代码的复用性,提升整体设计的整洁性。

4. 性能优化

  • 提升建议
    • 在处理电路连接和状态显示时,考虑使用数据缓存和更高效的查找结构(如树或图)来优化效率。
    • 研究并实现适用于特定使用场景的算法,以进一步提升处理速度,尤其是在电路设备数量较多时。

结论

通过这三次编程任务的实践,不仅增强了自身的编程能力,还培养了对系统化设计的理解。任务之间的迭代关系以及对不同复杂度需求的应对,锻炼了面向对象设计能力和代码优化能力。为了进一步提高系统的质量与易用性,必须从增强用户输入验证、完善文档、引导清晰的错误处理等方面入手不断优化。代码整体结构清晰,职责划分合理,但在可读性、可维护性和健壮性方面有改进空间。通过添加注释、减少代码冗余、降低类之间的耦合度、优化算法和数据结构、加强输入验证和异常处理,可以提高代码的整体质量。通过这些措施,可以确保开发出来的系统在功能完整的基础上,具备出色的健壮性和性能表现。

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

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

相关文章

ffmpeg 时基转换

1:av_q2d(AVRational a)函数av_q2d(AVRational);该函数负责把AVRational结构转换成double,通过这个函数可以计算出某一帧在视频中的时间位置 timestamp(秒) = pts * av_q2d(st->time_base); 计算视频长度的方法: time(秒) = st->duration * av_q2d(st->…

2024-2025-1学号20241309《计算机基础与程序设计》第九周学习总结

作业信息这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 2024-2025-1计算机基础与程序设计第九周作业这个作业的目标|作业正文|2024-2025-1学号20241309《计算机基础与程序设计》第九周学习总结 教材学习内容总结 《计算机科学概论》第十章: (一)…

docker网络互通实验

需求:创建两个自定义容器,分别使用自定义网络,使其互通1. 创建容器 docker run -d --name web1 -p 80:80 httpd 2. 创建网络 docker network create --driver bridge --subnet 192.168.1.0/24 net1 docker network create --driver bridge --subnet 171.16.1.0/24 net2 …

Windows下命令行及Java+Tesseract-OCR对图像进行(字母+数字+中文)识别,亲测可行

第一步:下载Tesseract OCR引擎安装包 访问Tesseract的GitHub发布页面(https://github.com/tesseract-ocr/tesseract)或第三方下载站点(https://digi.bib.uni-mannheim.de/tesseract/),下载适合你操作系统的版本(最新版本)。 推荐使用第三方下载:第二步:详细阐述一下第…

海思 uboot 编译

用默认配置烧录:本文来自博客园,作者:封兴旺,转载请注明原文链接:https://www.cnblogs.com/fxw1/p/18564721

java-BLOG-2

1.前言: 第四次题目集: 这次题目集的第一和第二个题目比较简单,很容易可以做出来,只是用到了一个新的知识点——继承,继承(Inheritance)是面向对象编程的核心特性之一。它允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码复用和功能扩展。继承是通过e…

用Java实现AI人脸比对

AI人脸比对技术百度智能云注册 https://login.bce.baidu.com/?account=&redirect=https%3A%2F%2Fconsole.bce.baidu.com%2Fiam%2F#/iam/baseinfo 选择人工智能-->人脸识别认证选择-->立即使用选择免费尝鲜(领取之后五分钟就可以在我的应用里查看了,里面勾选所有的…

NR中各种ID

NCGI(NR CELL Global Identifier):全球标识一个 NR 小区的号码PLMN(Public Land Mobile Network):国家码 MCC(Mobile Country Code)+网络码 MNC(Mobile NetWork Code),此号码唯一标识了某一个国家的某一个运营商NCI(NR CELL ID):标识 NR 中的一个 CELL GNBID:唯一标识一个基…

OOPTA4-6习题集总结

(1)前言 这三次作业算是一个渐进和转折的过程,题目渐渐减少,主要还是要写迭代题,对我来说5-6难度还是蛮大的。4是让我学会了不少更新功能的思路和调试的方法。5-6则让我明白了代码结构的重要性。题目内容主要涉及类的设计等等,以及主要的答题判题程序还有电路系统的编写与…

第53篇 调用第三方接口时需要注意的点

前言 在我们的业务开发中,调用第三方接口已经成为常态,比如对接一些ERP系统、WMS系统、一些数据服务系统等,它极大地扩展了我们应用的功能和服务范围。然而,实际对接过程中,我们往往会在这一环节遇到各种意想不到的问题,本文将深入探讨几种常见的第三方接口调用难题及其应…

如何在360评估中控制得分分布?

得分分布控制作用于评估打分时,评价人对一组被评价人的打分高低进行限制,避免老好人都打高分或恶意都给打低分的情况。 得分分布控制包括总分分布控制和各个指标的得分分布控制。注意 得分分布控制仅针对一个评价人同时评价多个被评价人时才会产生效果。 设置了得分分布控制时…