一、前言
知识点:面向对象设计的原则,如封装、单一职责,用正则表达式匹配,集合框架的使用,动态数组。
题量和难度都是依次递加的。
二、设计与分析
1.第一次作业:
输入格式处理:
处理整数输入,确保题号符合要求(首位不为0)。
解析题目内容,包括题目编号、问题和答案。(正则表达式的使用,字符串的分割)
分割答题信息,确保答案数量与题目数量一致
数据结构设计:
设计题目类,包含题目编号、内容和标准答案,以及判题方法。保存一道题目的信息以及处理的方法。
设计试卷类,包含题目列表和题目数量,以及判题方法。保存和处理一张试卷的信息以及处理的方法
设计答卷类,包含试卷对象、答案列表和判题列表,以及判题方法和输出方法。保存和处理一张答卷的信息以及处理的方法
逻辑判断:
实现题目类的判题方法,比较答题答案和标准答案。
实现试卷类的判题方法,通过题号找到对应的标准答案进行比较。
实现答卷类的判题方法,通过题号找到对应的答案进行判分。
2.第二次作业:
输入格式理解:
题目信息:包含题目编号、问题和标准答案,题号可以缺失。
试卷信息:包含试卷编号和题目编号以及对应的分值,多个题目可以用空格分隔。
答卷信息:包含试卷编号和答案,答案之间用空格分隔,缺少答案的题目记为0分,多余答案被忽略。
输出格式理解:
试卷总分警示:当试卷总分不等于100分时输出警示信息。
答卷信息:每道题的答题信息,包括题目内容、答案和判题结果(对/错)。判分信息:每道题的得分和总分,顺序与答题信息中的顺序相同。
提示错误的试卷号:当答卷中出现的试卷编号无法在题目信息中找到时输出错误信息。
设计建议:
在第一道题的基础上加上试卷题目类(试卷中的题目序 号与题目本身的题号不一致。且题目在不同试卷中的分值可能不一样),包含试卷中题目的顺序号,题目类的对象,题目分值,判断题目得分的方法。
试卷类要新增保存总分,保存题目数量,获得总分的方法。
答案类新增计算得分的方法。
答卷类新增输出得分及总分的方法。
3.第三次作业
删除题目信息以独行输入,用于删除一道题目信息。题目被删除后,引用该题目的试卷依然有效,但被删除的题目将以0分计,同时在输出答案时,题目内容与答案改为一条失效提示。
输出格式:
试卷总分警示:当一张试卷的总分分值不等于100分时,输出警示信息。
答卷信息:一行为一道题的答题信息,包括题目内容、答案和判题结果(true/false)。缺失答案的题目输出"answer is null"。
判分信息:输出一条答题记录所对应试卷的每道小题的计分以及总分,学号和姓名之间用英文空格分隔。
被删除的题目提示信息:当某题目被试卷引用,同时被删除时,答案中输出提示信息。
题目引用错误提示信息:如果试卷错误地引用了一道不存在题号的试题,在输出学生答案时,提示”non-existent question~”加答案。
学号引用错误提示信息:如果答卷中的学号信息不在学生列表中,答案照常输出,判分时提示错误。
格式错误提示信息:输入信息只要不符合格式要求,均输出”wrong format:”+信息内容。
试卷号引用错误提示输出:如果答卷信息中试卷的编号找不到,则输出”the test paper number does not exist”,答卷中的答案不用输出。
三、踩坑心得
- 尝试直接引用 Question 类的 getContent 和 getStandardAnswer 方法,这是不正确的。因为这两个方法是实例方法,需要通过一个 Question 对象来调用。
- getContent 和 getStandardAnswer 方法需要通过对象来调用,而不是通过类名。遍历 ArrayList
中的每个 Question 对象,并使用每个对象来调用 getContent 和 getStandardAnswer 方法。
3.信息打乱顺序输入 - 用户可能输入错误的格式,如题号、标准答案格式等。使用正则表达式或其他字符串匹配技术检查输入格式是否正确并在发现错误时提供明确的错误信息。
- 试卷信息中的题目编号可能与题目信息中的编号不对应。在处理试卷信息时,验证题目编号是否与题目信息中的编号一致,不一致时给出错误提示。
- 学生信息中的学号可能与答卷信息中的学号不对应。在判分时检查学号是否与学生信息列表中的学号匹配,不匹配时给出错误提示,并忽略对应答卷信息。
- 删除题目信息后,相关试卷和学生的答案如何处理。在删除题目后,更新试卷信息,将删除的题目在试卷中以0分计,并在答题信息中提供相应的失效提示。
- 用户输入的答案可能包含多余空格或其他格式问题。在答案解析时去除首尾多余空格,确保答案格式正确。
四、改进建议:
AnswerPaper 类中的 printQ_A 和 getJudge 方法使用了 TestPaper.getContent().get(num - 1);,这并不是一个好的设计。AnswerPaper 应该只与 TestPaper 有最小的交互,并且最好是通过接口或回调方法来获取内容。
Map<Integer, Integer> 用于存储问题和分数可能不是最佳选择,因为问题可能有多个分数(例如,选择题可能有一个或多个正确答案)。可能需要一个更复杂的数据结构来存储这种关系。
Map<Integer, String> 用于存储答案可能也不是最佳选择,因为一个问题可能有多个答案。
重复的代码模式,例如 for 循环中的 i < tokens.length。可以通过方法重用来减少重复代码。
五、总结
通过三次作业,进一步学习了如何合理的进行类设计,以及类间关系、单一职责、封装性等的实现,自学了正则表达式以及关于字符串、数组的很多便捷的方法,还弥补了许多语法问题,存在的很大问题就是拖沓,拖到最后两天做,基本得不到什么分,还是要先把线上慕课看完再课上听老师讲更高效,要不然课上还是听不懂。