题目集4~6的总结性Blog
前言:
在本阶段的课程设计中,我参与了三次题目集的练习和编程任务。这些题目不仅涵盖了从简单到复杂的算法和数据结构问题,还涉及了实际应用中常见的题目类型,包括选择题、填空题、以及更具挑战性的编程题。这些题目的难度逐步加大,不仅考察了基础的语法和算法知识,还需要我们深入理解题目背景,进行更加细致的逻辑推理。
题目数量:
- 题目集一:大多数题目集中在数据结构与基本算法的应用,如链表操作、数组排序等,题量适中。整体难度偏基础,主要考察编程语言的基本运用及基础算法的实现。
- 题目集二:难度相较上次有所提高,涉及了更多的边界条件处理和复杂的数据结构应用,如二叉树的深度遍历、图的广度优先搜索等。这一题集不仅考察了基础算法的掌握,还加强了对边界情况的思考。
- 题目集三:难度逐步加大,特别是在涉及多线程、复杂数据解析以及多选题和填空题的处理时,难度明显增加。部分题目要求我们通过自定义数据结构和算法来优化性能,如使用哈希表进行高效查找等。
通过这三次题目集的训练,我对编程语言的掌握更加深入,尤其是在数据处理、算法设计、以及程序调试方面积累了宝贵的经验。
设计与分析:
在此次博客中,我将分析题目集四中题目答题判题程序-4和家居强电电路模拟程序-2
(1) 答题判题程序-4
题目要求:
这道题目的设计要求包括输入题目信息、试卷信息、学生信息、答卷信息以及删除题目信息等,并根据标准答案判断学生的答题结果。

代码分析
这道题目相对复杂,要求我们设计一个答题判题程序,模拟一个小型的测试系统,以下是我对程序设计及其源码的分析。
class Input {
private String inputData;
public Input() {}
public Input(String data) {
this.inputData = data;
}
public int judgeInput() {
if(inputData.matches("#N:\\d+\\s+#Q:[^#]*#A:.*") ||
inputData.matches("#K:\\d+\\s+#Q:[^#]*#A:.*") ||
inputData.matches("#Z:\\d+\\s+#Q:[^#]*#A:.*")) {
return 1;
} else if(inputData.matches("(#T:\\d+){1}(\\s+[0-9]+-[0-9]+){0,}\\s*")) {
return 2;
} else if(inputData.matches("(\\s*#S:\\s*){1}(\\d+\\s+\\d+\\s*){1}(\\s*#A:\\s*\\d+-[^#]*){0,}\\s*")) {
return 3;
} else if(inputData.matches("(\\s*#X:\\s*){1}(\\d+\\s+[^- ]+-){0,}(\\d+\\s+.+){1}\\s*")) {
return 4;
} else if(inputData.matches("\\s*#D:\\s*N-\\d+\\s*")) {
return 5;
} else if(inputData.contains("end")) {
return 6;
} else {
return 0; // 输入格式不合法
}
}
// 获得创建的试卷中的信息
public int[] getPaper() {
inputData = inputData.replaceAll("#T:", "").trim().replaceAll("-", " ");
String[] inputTemp = inputData.split("\\s+");
int[] inputNums = new int[inputTemp.length];
for (int i = 0; i < inputTemp.length; i++) {
inputNums[i] = Integer.parseInt(inputTemp[i]);
}
return inputNums;
}
// 获得题目
public Problem getProblem() {
String[] inputSegments;
int num = 0;
String question = "", answer = "";
int kind = 0;
if (inputData.contains("#N:")) kind = 0;
else if (inputData.contains("#Z:")) kind = 1;
else if (inputData.contains("#K:")) kind = 2;
inputData = inputData.replaceAll("^#", "");
inputSegments = inputData.split("#");
for (String segment : inputSegments) {
if (segment.contains("N:") || segment.contains("K:") || segment.contains("Z:")) {
segment = segment.replaceAll("N:|K:|Z:", "").trim();
num = Integer.parseInt(segment);
} else if (segment.contains("Q:")) {
question = segment.replaceAll("Q:", "").trim();
} else if (segment.contains("A:")) {
answer = segment.replaceAll("A:", "").trim();
}
}
if (kind == 0) {
return new Problem(num, question, answer);
} else if (kind == 1) {
return new ChoiceProblem(num, question, answer);
} else {
return new FillProblem(num, question, answer);
}
}
// 获取单次(单张试卷)的回答
public String[] getAnswer() {
inputData = inputData.replaceAll("#S:", "").trim();
String[] inputTemp = inputData.split("-|#A:");
for (int i = 0; i < inputTemp.length; i++) {
inputTemp[i] = inputTemp[i].trim();
}
return inputTemp;
}
// 获得学生信息(学号、姓名)
public String[] getStudent() {
inputData = inputData.replaceAll("#X:", "").replaceAll("-", " ").trim();
return inputData.split("\\s+");
}
// 获得删除的题号
public int getDelete() {
inputData = inputData.replaceAll("#D:", "").replaceAll("N-", "").trim();
return Integer.parseInt(inputData);
}
public String getInput() {
return inputData;
}
public void setInput(String input) {
this.inputData = input;
}
}
在上述代码中,我们通过getProblem() 函数来解析输入的题目信息,并存储题目的编号、内容及标准答案。使用字典结构方便后续查询和处理。
数据结构选择与设计
题目信息(questions):选择字典来存储题目信息是因为题目的编号是唯一的,字典的查找时间复杂度为O(1),能够快速匹配。
学生信息(students):学生信息以学号为键,姓名为值的方式存储,便于查找学生成绩。
复杂度分析
通过对代码的逐步分析,题目要求的基本功能包括:
1.解析题目信息
2.解析试卷信息
3.判题和评分
4.处理删除题目的信息
时间复杂度:
解析题目信息和试卷信息的时间复杂度为O(n),其中n为题目和试卷的数量。
判题时,需要逐一比较答案,因此时间复杂度为O(m),其中m为学生答题的数量。
采坑心得:
在开发过程中,我遇到了几个重要问题,需要总结和分享这些“采坑”心得:
问题:输入顺序不一致
o题目信息、试卷信息、学生信息以及答卷信息的输入顺序不固定。虽然题目要求保证输入格式正确,但顺序不一致会导致代码在解析数据时容易出错,尤其是在处理试卷编号和题目编号时。
o解决方案:通过优先解析“#T:”行中的试卷信息,再根据题目编号匹配相关的答案。使用字典存储题目信息,能够让我们根据题目编号快速查找到对应的答案。
问题:题目删除功能的实现
o删除题目时,原本的题目信息并不被清除,而是显示为“无效”或“0分”。这在实现时需要特别注意,尤其是在答卷评分时,如何识别和处理被删除的题目。
o解决方案:在判题时,如果发现题目已被删除,则直接判为无效并给0分。
问题:部分答案正确的处理
o多选题和填空题需要判定部分正确的情况。处理此类题目时,首先要判断答案是否包含所有正确项,然后计算部分得分。
o解决方案:对于多选题,我采用了将标准答案和学生答案转化为集合进行比较的方法,判断是否完全正确或部分正确。
改进建议:
在编写答题判题程序时,我认为以下几点可以进一步改进:
增强输入数据验证
o目前的程序没有对输入数据进行充分的验证,可能会导致非法数据(如格式错误、无效题目编号等)导致程序崩溃。可以通过正则表达式增强输入的验证,确保数据格式正确。
优化部分答案的判定逻辑
o对于部分答案的处理,当前代码中采用的方式较为简陋,可以考虑引入更复杂的评分算法。例如,在多选题中,判断学生是否选对了所有正确答案,并根据选错答案的数量进行扣分。
改进界面设计
o目前的程序仅通过命令行输出结果,如果能够提供一个图形化界面(GUI)来展示学生的答题情况和评分,将大大提升用户体验,尤其是在处理多道题目时,能够更直观地查看学生的表现。
(2) 家居强电电路模拟程序-2
题目要求:
设计一个简单的电路模拟系统,要求能够解析用户输入的电路配置数据,并能够模拟电流、电压的计算与动态变化,同时支持开关控制和组件状态更新,最终展示电路的运行状态。系统需要能够支持简单的串联电路,并具备用户交互功能。

类设计
CircuitDiagram 类
1.功能:负责电路图的模拟与管理,计算电路中每个组件的电流与电压,并实时更新电路状态。
2.方法:
1.renew(): 更新电路中每个组件的状态(电流、电压)。
2.showInfo(): 输出电路状态信息,帮助用户查看电路运行情况。

Input 类
1.功能:解析用户输入的电路配置,转化为可操作的数据结构。
2.方法:
1.splitCircuit(): 根据输入的电路数据,拆解出电路中各个组件。
2.judgeInput(): 验证输入数据的有效性,确保电路配置符合规则。

Controller 类
1.功能:负责管理电路的输入与操作,控制电路的状态变化。
2.方法:
1.inputCircuit(): 处理用户输入,构建电路模型。
2.operation(): 执行用户的操作命令(如改变开关状态、调节电压等)。

设计分析
-
电路模拟核心
系统通过计算电路中的电流与电压来模拟实际电路的运行。每个组件(如电阻、开关)根据电流的大小调整电压,renew() 方法完成这一核心计算,并动态更新电路状态。 -
输入解析与电路构建
Input 类通过方法如 splitCircuit() 解析用户输入的电路配置(例如:Z27XC48VB31N1M4Q),将其转换为电路组件,并使用 judgeInput() 验证输入的合法性。 -
组件控制与状态更新
系统支持用户对电路组件的操作,如开关控制、调节电流和电压等。通过调用 operation() 方法,用户能够实时控制电路状态,而 showInfo() 方法则提供电路状态的即时反馈。 -
电路连接与拓扑结构
当前系统设计主要支持串联电路,splitCircuit() 和 renew() 方法将电路组件按用户输入进行连接,并在电路变化时更新状态。 -
扩展性与优化
该设计可扩展以支持并联电路或更复杂的电路拓扑。也可以加入更多的电路组件,如电容、电感等。性能优化方面,可以减少重复计算,提升大规模电路模拟的效率。
提交的源码分析
- 代码结构:代码按功能模块进行划分,CircuitDiagram 类负责电路的核心模拟,Input 类负责解析与验证用户输入,Controller 类负责交互控制,具有清晰的职责分离。
- 功能实现:通过 splitCircuit() 方法,代码能够高效地将用户输入的数据转化为电路组件。renew() 方法根据电流和电压的变化动态更新电路状态,确保模拟的准确性。
- 交互与反馈:系统能够根据用户输入的电路配置实时展示电路的状态变化,反馈机制简洁明了,用户可以直观地看到电路的工作情况。
心得体会
通过这次电路模拟系统的设计与实现,我加深了对电路模拟与计算的理解,特别是电流与电压的动态变化与控制。此外,在解析用户输入时,处理数据结构和验证有效性是非常重要的步骤,这有助于避免错误输入导致的系统崩溃。
我还认识到模块化设计的重要性,代码结构的清晰和模块之间的解耦使得整个系统易于扩展与维护。在实际开发中,如果没有良好的类设计和数据结构规划,后期维护和修改将变得困难。
采坑心得
输入数据的处理
在解析输入数据时,遇到过输入格式不一致的问题,尤其是在不同格式的电路图配置数据之间进行转换时,格式验证非常关键。judgeInput() 方法的设计帮助我避免了输入不规范的数据对系统运行的影响。
性能问题
电路模拟过程中,当涉及到大量组件时,性能成为了瓶颈。特别是 renew() 方法每次都要遍历整个电路进行计算,这在电路复杂度较高时导致了计算效率低下。对此,我考虑到未来可以通过引入缓存机制或者优化计算公式来提升性能。
拓扑结构的支持
目前系统仅支持串联电路,这意味着如果用户输入复杂的并联电路配置,系统无法正确处理。为了提高系统的通用性,需要对电路拓扑的解析逻辑进行扩展,支持并联和混合电路的处理。
改进建议
通过这次题目集的练习,我对代码设计提出了以下几点改进建议:
- 增强性能
对于电路模拟中的大量计算,可以通过优化计算方法或者引入缓存机制来提升性能,特别是在电路较为复杂时,避免重复计算。 - 支持更复杂的电路拓扑
当前系统仅支持串联电路,建议扩展系统,支持并联电路、混合电路等更多复杂电路拓扑的模拟。 - 模块化设计与复用性
进一步提升代码的模块化程度,确保每个功能模块具有较高的复用性。可以将电路组件与控制逻辑解耦,使得不同电路组件可以根据需要灵活替换或扩展。 - 图形界面
目前的系统仅提供命令行输入与反馈,建议未来添加图形界面,使用户能够直观地设计电路、查看电路状态并进行操作。这将极大提升用户体验,特别是在设计复杂电路时。 - 输入格式与验证
输入格式和验证的处理是系统中至关重要的部分,建议在输入数据解析时增加更多的格式检查和容错处理,确保用户输入时可以容忍一些常见的格式错误。
总结:对本阶段三次题目集的综合性总结
经过这三次题目集的练习,我收获了很多宝贵的编程经验和解决问题的技巧。每一次完成作业后,我都能感觉到自己对编程的理解和能力在不断提升。特别是在处理复杂题目时,我能够更加熟练地运用算法和数据结构来解决问题。
学到了什么:
- 如何在不确定输入顺序的情况下正确解析数据。
- 如何判断部分答案正确,并根据不同情况给出不同的评分。
- 如何优化代码性能,使得复杂数据的处理更加高效。
- 对复杂算法的优化,尤其是在处理大规模数据时,如何减少时间复杂度。
- 更深入地学习面向对象编程(OOP)和设计模式,在复杂的程序设计中应用这些思想。
- 课程内容上可以增加更多的实际应用案例,帮助我们理解如何将所学知识应用于真实的工程项目中。
- 对于作业和实验,可以引导我们在解决问题时进行更多的思考和讨论,提供更多的挑战性题目。
总之,这三次题目集的实践让我收获颇丰,不仅提升了编程能力,还加深了对程序设计与算法的理解,为今后的学习打下了坚实的基础。

浙公网安备 33010602011771号