BLOG-1
pta1-3次大作业博客总结一、媒介
在前三次的PTA大作业中,我们依次完成了答题判题步伐1至3。这三个步伐彼此紧密相连,层层递进,每一次的完成都是在前一次底子上的一连修改、完善与优化。这三次大作业的顺利进行要求我们对类、Map、List、正则表达式等知识点有深入的明确与熟练的运用。从一开始,我们就需要构建一个合理的结构,由于这三个标题是紧密相扣的。
1.答题判题步伐1
答题判题步伐1的任务是模仿一个小型的测试体系,要求输入标题信息和答题信息,并根据标题信息中的尺度答案来判断答题的结果。这个过程不仅需要准确地解析和处理输入数据,还要求我们设计合理的算法来评估答案的正确性。
为了顺利完成这个标题,我们必须熟练掌握多种知识点,包括类的使用、字符串的分割、以及集合框架中的Map和List等。该标题的题量和难度均为中等,得当用来锻炼我们的编程能力和逻辑头脑。
对我而言,作为一名从未接触过面向对象编程的初学者,这个任务在最初接办时确实显得有些棘手。面对面向对象的概念、类的设计以及如何高效地存储和处理数据,我需要耗费额外的时间进行明确和练习。然而,经过不断的积极和实行,我逐渐掌握了这些知识,并成功地完成了这个步伐。
2.答题判题步伐2
答题判题步伐2相比于答题判题步伐1新增了试卷信息模块。为顺利完成此题,我们同样需要熟练掌握类的使用、字符串的分割利用,以及集合框架中的Map和List等。这个标题的题量以及难度都属于中等。
3.答题判题步伐3
答题判题步伐3在答题判题步伐2的底子上新增了学生信息管理和标题信息删除功能。除了前面提到的知识点外,要完成此标题还需我们熟练掌握正则表达式,以判断输入格式的正确性。相比前两次PTA任务,第三次因新增了更多输入输出判断,题量和难度均大幅提升,完成此任务需要投入较多的时间和精力。
二、设计分析
1.答题判题步伐1
本标题要求设计一个答题步伐,用于模仿小型测试。步伐需输入标题信息和用户答题信息,并依据标题信息中的尺度答案判定答题结果。
为实现此功能,我们设计了四个核心类:
[*]标题类:用于封装每道标题的信息,包括标题描述、选项(如有)、尺度答案等内容,便于同一存储和访问。
[*]试卷类:用于管理所有标题实例,将标题信息会合封装,方便对整个标题集合进行利用。
[*]答卷类:用于封装用户的答题信息,将用户的每个答案与对应的尺度答案比对,以便进行评判和记录。
[*]主类:作为步伐的入口,负责接收并解析输入的标题信息和答题信息,调用上述各类的功能,实现标题加载、答题记录、结果盘算等功能。
通过这四个类的协作,步伐可以有用地管理标题、记录答案,并盘算出测试结果,使整个答题流程清晰流畅。
类图
https://img2023.cnblogs.com/blog/3261129/202410/3261129-20241025200227985-1936997960.png
时序图
https://img2023.cnblogs.com/blog/3261129/202410/3261129-20241025200227099-20615821.png
1.标题类
该类用于表现单个标题,包罗以部属性:标题编号、标题内容和尺度答案。类中界说了多种方法,支持基本的利用,例如设置和获取标题内容。此外,提供了答案校验方法,用于判断用户的回答是否正确。
//判断答案是否正确
public boolean isCorrect(String answer) {
return standardAnswer.trim().equals(answer.trim());
}2.试卷类
该类用于表现一组标题集合,使用 Map 结构来存储多个标题。类中包罗了一些底子利用方法,如添加标题、删除标题、查找标题等。
3.答卷类
该类用于存储用户输入的答案、试卷信息及判题结果。类中包罗以下重要属性:paper(试卷类实例)、Map 类型的答案集合、以及 Map 类型的判题结果集合。重要利用包括生存答案、进行判题等功能,其中判题方法是该类的核心功能,用于对比用户答案与正确答案并生成结果。
判题方法首先通过 for 循环遍历试卷中的每个问题,使用 paper.getAllQuestions() 获取所有问题列表并依次进行评估。对于每个问题,从 answers 中提取用户的回答,并检查是否为空 (answer != null)。终极,所有标题的评估结果都会记录在 results 集合中。
// 判题方法
public void evaluateAnswers() {
for (Question question : paper.getAllQuestions()) {
String answer = answers.get(question.getQuestionNumber());
if (answer != null) {
boolean result = question.isCorrect(answer);
results.put(question.getQuestionNumber()-1, String.valueOf(result));
} else {
results.put(question.getQuestionNumber()-1,"false");
}
}
}
}4.主类
该类综合调用了前面提到的三个类,用于实现标题的完整功能。其重要职责是接收用户输入,解析标题信息和答卷数据,并将其通报给相关模块进行处理,从而完成对标题的管理和答卷评判等任务。
2.答题判题步伐2
答题判题步伐2在答题判题步伐1的底子上新增了试卷信息,并且这三种信息可能会被打乱次序混合输入。
为实现此功能,我在答题判题步伐1的底子上进行了以下改进:
[*]试卷类:增加了试卷编号、分数和总分等属性。
[*]答卷类:新增了试卷有用性判断标志,并调解了答案评估函数。
[*]主类:明显优化了输入解析代码,以支持信息的乱序处理。
类图
https://img2023.cnblogs.com/blog/3261129/202410/3261129-20241025200226596-122585639.png
时序图
https://img2023.cnblogs.com/blog/3261129/202410/3261129-20241025200225943-1842682244.png
1.试卷类
增加了试卷编号、分数和总分等属性及其相关基本利用。
2.答卷类
对其核心函数答案评估进行了大幅修改
相比于答题判题步伐1,答题判题步伐2的答案评估函数进行了一下修改:
[*]增加了试卷有用性检查:在评估答案前,新增了对试卷有用性的判断逻辑,如果试卷无效(getEffectiveness() == -1),直接输出提示并竣事评估。
[*]处理了答案可能为空的环境:如果答案为空,会记录相应的输出内容,且分数不会增加。
[*]详细的输出和分数记录:对每道题的评估结果进行了详细输出,包括标题、答案和是否正确的标志(question.getQuestion() + "~" + answer + "~" + isCorrect)。同时,还将每道题的分数存入resultScores列表,并终极输出各题分数及总分。
[*]盘算总分:通过遍历所有标题,盘算并累积每道题的分数,终极输出总分。
[*]逐题输出结果与分数格式化输出:输出每道题的评估结果以及分数列表,并使用格式化输出的方式将各题分数和总分进行组合表现。
3.主类
相比于答题判题步伐1,答题判题步伐2的主类优化完善了用户输入解析部分,进行了以下改进:
[*]支持多个试卷和答卷的管理:通过papers和answerSheets两个集合来管理多个试卷和答卷。
[*]输入格式更加灵活:允许通过特定标识符(如#N:, #T:, #S:)来识别输入的差别类型(标题、试卷、答卷)。
[*]增加了总分校验:创建试卷时,校验每张试卷的总分是否达到100分,如果不敷,则会输出警告。
[*]处理无效答卷:通过设置Effectiveness字段来标识答卷的有用性。如果试卷不存在或无效,步伐会提示“试卷编号不存在”。
[*]代码结构更清晰:改进的代码分离了标题解析、试卷解析和答卷解析的逻辑,使每个解析模块更加独立,逻辑更清晰。
3.答题判题步伐3
答题判题步伐3相比于前两次难度大幅提升,相比于前两次,第三次,第三次新增了学生信息、删除信息,以及大量格式判断。
为完成该标题,在前两次的底子上,进行了以下修改:
[*]试卷类:新加了删除标题函数。
[*]答卷类:对评估函数又一次进行了完善以及优化。
[*]学生类:新增了学生类,存储学生信息。
[*]题库类:新增了题库类,存储标题。
[*]匹配类:新增匹配类,判断字符串是否合法。
类图
https://img2023.cnblogs.com/blog/3261129/202410/3261129-20241025200225282-642466814.png
时序图
https://img2023.cnblogs.com/blog/3261129/202410/3261129-20241025200224303-1952518010.png
1.答卷类
又一次对评估答案函数进行了进一步完善与优化:
[*]增强了对试卷和题库的有用性检查:在evaluateAnswers方法中增加了对questionBank和paper对象的空值检查,确保这些对象已正确初始化,避免了可能的空指针非常。
[*]细化的评分处理:在循环中根据差别环境将各题得分结果存储在resultScores中,不仅盘算总分数,还将各题的分数单独存储,便于后续分析。
[*]改进输出结构:在输出总成绩时,添加了学生的基本信息(学号和姓名)的判定。
[*]支持非尺度环境的处理: 参加了对题号不存在、标题被删除、标题不在试卷中的判断条件。针对无效试卷的环境,设置了输出“non-existent question~0”和“the question X invalid~0”。
2.学生类
界说了属性学号姓名及其基本利用。
3.匹配类
匹配类中界说了isVaild方法,使用正则表达式判断输入是否合法。
public boolean ifvaild(String line) {
// 匹配题目
if (Pattern.compile("^#N:\\d+ #Q:.+ #A:[\\w\\d]+.*$").matcher(line).matches()) {
return true;
}
// 匹配试卷
else if (Pattern.compile("^#T:\\d+(\\s\\d+-[\\d\\w]+)*\\s*$").matcher(line).matches()) {
return true;
}
// 匹配答卷
else if (Pattern.compile("#S:(\\d+) (\\d+) (.+)").matcher(line).matches()) {
return true;
}
// 匹配学生
else if (Pattern.compile("^#X:\\d{8} \\w+(-\\d{8} \\w+)*$").matcher(line).matches()) {
return true;
}
// 匹配删除题目
else if (Pattern.compile("^#D:N-\\d+$").matcher(line).matches()) {
return true;
}
// 如果都不匹配,则返回false
return false;
}三、踩坑心得
[*]在编写答题判题步伐2时,我始终无法通过答卷有用性判断的测试点,于是加了一个属性effectiveness来判断答卷有用性。
private int effectiveness;if (getEffectiveness() == -1) {
System.out.println("The test paper number does not exist");
return; // 如果有效性为 -1,则直接返回,不再评估答案
}
[*]在编写答题判题步伐1和2时,由于对如何匹配正确的字符串格式不够清晰,我采用了相对复杂的方法来实现这一功能,通过使用substring以及split以及循环来分解输入的字符。
[*]由于在编写答题判题步伐1和2时完全没有思量输入格式的问题,因此在开发答题判题步伐3时,出现了很多测试点返回非零值的环境。
[*]在编写答题判题步伐3时,无效试卷的引用信息与输出的标题信息之间一连发生辩论,这导致我始终无法通过测试点4。
// 题号是否在题库中存在
else if (!questionBank.getQuestionBank().containsKey(questionPaper.getQuestionNumber())
|| question.getQuestion().equals("-1")) {
output = "non-existent question~0";
score = 0;
}
// 題目是否被刪除
else if (question.getQuestionNumber() == paper.getDeleteNum()) {
score = paper.getQuestionScore(question.getQuestionNumber());
output = "the question " + question.getQuestionNumber() + " invalid~0";
}
[*]在编写答题判题步伐3时,删除标题时直接将其移除,导致无法将被删除标题的分数赋为0。为相识决这个问题,我首先将所有标题的分数初始化为0,随后在遍历时再将未删除标题的分数重新赋值。
// 试卷所有分数置0
for (int score : paper.getScoreMap().values()) {
score = 0;
resultScores.put(j, score);
j++;
}
[*]由于答题判题步伐1和2的难度相对较低,设计上相对简单,团体结构仅包罗三个类,功能划分也并不非常细致。这种设计使得答卷类承载了过多的内容,导致在编写答题判题步伐3时遇到了诸多挑战。随着第三次题量的大幅增加,步伐需要处理的格式判断变得复杂,新增的内容和类也相应增多,修改和调解的地方也非常多。为相识决这些问题,不得不耗费大量的时间进行重新设计和优化,以确保体系能够高效、准确地处理更多的标题和复杂的判断逻辑。
[*]答题判题步伐1和2的代码注释相对较少,这给后续的开发工作带来了困难。在编写答题判题步伐3时,我时常需要回顾之前的代码,以便更好地明确某些功能块的详细作用和实现逻辑。缺乏细致的注释使得我在阅读代码时无法敏捷捕捉到每一段代码的意图,增加了开发过程中的时间成本。
四、改进建议
[*]确保注释尽可能详细,以便于后续的阅读和修改。在代码中使用清晰的注释能够帮助本身快速明确代码的功能、逻辑和设计意图。每个函数、变量和重要的逻辑分支都应有相应的解释,以便于本身能够轻松跟踪和维护代码,方便后续的多次开发。
[*]在设计类时,应只管寻求精致化,切忌将所有功能和属性堆砌在一个类中。这种做法不仅会导致类的复杂性增加,还会使得后续的开发和维护变得极为困难。一个过于巨大的类难以明确和测试,容易引发错误。合理划分职责、创建小而专注的类,可以提升代码的可读性和可维护性,使得每个类都负担特定的功能。这样一来,修改或扩展某一部分的功能时,只需关注相关的类,提高了开发效率。
[*]掌握正则表达式的使用非常重要,它能够明显提高编程效率并使代码更加简洁,能够高效地处理字符串的搜刮、匹配和替换等任务。通过正确运用正则表达式,可以减少冗余代码,从而简化逻辑和优化步伐性能。
[*]扎实底子知识是编写高质量代码的关键,特殊是在数据结构的应用上。正确和合理地使用如 Map、List 和队列等数据结构,可以极大地提升代码的结构性和可维护性。掌握这些基本的数据结构,不仅能帮助你解决实际问题,还能使你的代码逻辑更加清晰,结构更加合理,从而为后续的开发和维护打下坚实的底子。
[*]在编写代码时,应充分思量各种可能的环境,尤其是要防止非常值的输入。这种前瞻性的头脑能够有用提高代码的结实性和稳定性。处理输入时,进行严格的验证和筛选是至关重要的,以确保步伐能够正确处理用户输入的各种形式。
五、总结
在此次这三次大作业中,我们逐步完成了三个答题判题步伐的开发,每个步伐都是在前一个的底子上进行了改进与扩展。这频频大作业不仅加深了我对面向对象编程、数据结构和算法设计等知识的明确,还提升了我解决实际问题的能力。
在第一个答题判题步伐中,要求设计一个基本的测试体系,输入标题信息和答题信息,并通过尺度答案进行判断。这一过程要求我们熟练掌握类的设计、字符串的处理及集合框架的运用。作为一个初学者,我在学习如何设计类及其交互时遇到了一些困难,但在不断的实践中,我逐渐掌握了相关的知识并成功实现了步伐功能。
第二个步伐在第一步伐的底子上增加了试卷信息模块,处理复杂输入的需求。我在设计时,增加了试卷编号、分数等属性,并优化了输入解析的代码,以支持信息的乱序输入。这一改进不仅提升了步伐的灵活性,也让我对步伐设计的模块化有了更深的明确。
进入到第三个步伐时,我面临了更大的挑战。新增的学生信息管理、标题信息删除功能以合格式判断使得第三次大作业的复杂性大幅提升。在设计中,我创建了多个新类以分担各自的功能。此外,我运用正则表达式对输入格式进行验证,确保步伐在接收数据时的严谨性。这一过程让我深刻体会到底子知识的重要性,特殊是在数据结构和正则表达式的运用上。
通过这三次大作业,我不仅提升了编程技能,还培养了分析问题和解决问题的能力。遇到的诸多挑战,好比如何有用管理输入输出、如何进行数据的有用性检查、如那边理对象之间的关系,都促使我不断反思和调解我的设计思路。在此过程中,我也意识到注释的重要性,合理的注释不仅能帮助我明确代码,也为他人阅读和维护代码提供了便利。这次三次大作业让我在实践中不断学习和成长,明确了软件开发过程中的重要环节,如设计、实现、测试和维护。未来,我会继续增强这些方面的学习,尤其是提高代码的可读性与可维护性,力求在编写高质量代码的道路上不断前行。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]