java第1-3作业集blog

1.前言

本次blog主要是题目集1-3的总和,主要分析每次题目集中的最后一题,答题判断程序,每次最后一题难度增加。
题目集1
知识点:设计类,类和对象的使用,数组的基础应用以及关联类,以及Map<>, TreeMap ,List<>等数据结构;
题量:题目数为5题。
难度:前面4题简单,最后一题难度增加。
题目集2
知识点:类和对象的使用,链表的实用,类的方法以及HashMap等数据结构
题量:题目数为4题。
难度:前面3题简单,最后一题难度在上一次基础上增加。
答题判题程序-3
知识点:面向对象编程(封装性),正则表达式HashMap<>,LinkedHashMap<>,List<>。
题量:题目数为3题。
难度:第1题简单,第二题难度适中,最后一题难度在上一次基础上增加。
2.设计与分析
答题判题程序-1
这段代码实现了一个简单的答题程序,它按照指定的输入格式接收题目信息和学生的答案,然后根据标准答案判断学生答案的正确性。
类和对象设计
Quiz 类:
属性:题目编号(id)、题目描述(description)、标准答案(solution)。
方法:
构造函数:初始化题目的属性。
matchAnswer:判断给定的答案是否与标准答案匹配。
ExamSet 类:
属性:一个 TreeMap,用于存储 Quiz 对象,键为题目编号。
方法:
addQuiz:向 ExamSet 中添加一个新的 Quiz 对象。
validateAnswer:验证给定题目编号的答案是否正确。
formatQuestion:格式化输出题目描述和答案。
StudentResponses 类:
属性:
ExamSet 对象:用于访问题目信息。
答案列表(submissions):存储学生提交的答案。
结果列表(outcomes):存储每个答案的判题结果。
方法:
submitAnswer:提交学生答案。
gradeResponses:遍历答案列表,对每个答案进行判题。
display:输出每个问题的题目内容和学生的答案,以及判题结果。
主程序流程
输入处理:
使用 Scanner 类读取控制台输入。
首先读取题目数量,然后循环读取每个题目的详细信息,包括题号、题目描述和标准答案。
使用 split 方法解析输入的字符串,提取题目信息,并将其存储在 ExamSet 中。
答案处理:
继续读取输入,直到遇到 "end" 标记。
对于每组答案,使用 split 方法解析答案字符串,提取每个答案,并提交给 StudentResponses 对象。
判题和输出:
调用 StudentResponses 的 gradeResponses 方法,对所有提交的答案进行判题。
调用 display 方法,输出每个问题的题目内容和学生的答案,以及判题结果。

答题判题程序-2
在答题判题程序-1的基础上,答题判题程序-2增加了以下要求
试卷信息处理:除了题目信息和答题信息,还需要处理试卷信息,包括试卷号和题目分值。
分值处理:需要根据题目的分值来计算每道题的得分,并在输出中包含这些信息。
总分警示:当试卷的总分不等于100分时,需要输出警示信息。
答案数量处理:答题信息中的答案数量可能少于试卷中的题目数量,需要处理这种情况,没有答案的题目计0分。
无效试卷号处理:需要检查答题信息中的试卷号是否存在于试卷信息中,如果不存在,需要输出错误提示。
输入信息的混合和乱序:题目信息、试卷信息和答题信息可能会以任意顺序混合输入,增加了处理的复杂性。
试卷总分的验证:需要验证试卷的总分是否等于100分,并在不等于100分时输出警示信息。
答案与题目的对应:由于答案数量可能少于题目数量,需要正确地将答案与题目对应起来,并处理没有答案的题目。
试卷号的验证:需要验证答题信息中的试卷号是否有效,增加了程序的逻辑复杂度。
输出格式的复杂性:输出格式更加复杂,需要包含题目内容、答案、判题结果以及得分信息。
总的来说,答题判题程序-2在答题判题程序-1的基础上,增加了对试卷信息的处理,以及对分值、答案数量和试卷号的验证,使得程序的逻辑更加复杂,对输入数据的处理要求更高。
类和对象设计
Quiz 类:
属性:题目编号(id)、题目描述(description)、标准答案(solution)。
方法:
构造函数:初始化题目的属性。
matchAnswer:判断给定的答案是否与标准答案匹配。
TestPaper 类:
属性:试卷编号(paperId)、题目分数映射(quizScores)、总分(totalScore)。
方法:
构造函数:初始化试卷的属性。
addQuiz:向试卷中添加题目及其分数。
checkTotalScore:检查试卷的总分是否为100分,并在不是100分的情况下打印警告信息。
ExamSet 类:
属性:题目集合(quizzes)、试卷集合(testPapers)。
方法:
addQuiz:向考试系统中添加一个新的题目。
addTestPaper:向考试系统中添加一张新的试卷。
validateAndScoreAnswer:验证给定试卷编号的答案,并计算得分。
Main 类:
主程序流程,包括输入处理、题目信息处理、试卷信息处理、答卷信息处理。
主程序流程
输入处理:
使用 Scanner 类读取控制台输入。
收集所有输入,直到遇到 "end" 标记。
处理题目信息:
解析输入的题目信息,并将其存储在 ExamSet 的 quizzes 映射中。
处理试卷信息:
解析输入的试卷信息,并创建 TestPaper 对象,将其存储在 ExamSet 的 testPapers 映射中。
处理答卷信息:
解析输入的答卷信息,使用 ExamSet 的 validateAndScoreAnswer 方法来验证答案并计算得分。
输出结果:
输出每个问题的题目内容、学生的答案和判题结果。
输出每个试卷的总分警示(如果总分不是100分)。
输出判分信息。
心得
数据结构的选择:
使用 HashMap 来存储题目和试卷信息,因为它们提供了快速的查找性能,特别是当需要根据试卷编号或题目编号快速定位到特定试卷或题目时。
输入验证:
代码中没有显式的输入验证逻辑,这在实际应用中可能会导致问题。应该添加对输入数据的验证,确保数据的格式和类型正确。
测试:
应该编写测试用例来覆盖各种输入情况,包括边界情况和异常情况,确保程序的健壮性。
处理混合输入:
程序能够处理混合输入,即题目信息、试卷信息和答卷信息可能以任意顺序输入。这要求程序在处理输入时具有一定的灵活性和鲁棒性。
处理缺失答案:
程序能够正确处理缺失答案的情况,对于没有输入答案的题目计0分。这体现了程序的健壮性。

答题判题程序-3
在答题判题程序-2的基础上,这个新的答题程序进一步增加了以下
学生信息处理:需要处理学生信息,包括学号和姓名。
删除题目信息:增加了删除题目的操作,被删除的题目在答题时需要特别处理。
错误处理:需要处理更多的错误情况,包括格式错误、无效的试卷号引用、无效的学号引用等。
题目引用错误处理:需要检测试卷中引用的题目是否存在,如果引用了不存在的题目号,需要给出提示。
答案内容处理:需要处理答案内容中的空格,并在答案为空时给出相应处理。
信息处理的复杂性:除了题目、试卷、答卷信息,还需要处理学生信息和删除题目信息,增加了信息处理的复杂度。
错误检测和处理:需要检测和处理多种错误情况,包括格式错误、无效引用等,并对这些错误给出相应的提示。
逻辑判断的复杂性:在判题时,需要考虑题目是否被删除、是否被错误引用等因素,增加了逻辑判断的复杂性。
输出格式的复杂性:输出格式需要包含更多的信息,如学生信息、题目的失效提示、错误提示等,使得输出更加复杂。
数据一致性维护:在删除题目或发现无效引用时,需要确保数据的一致性,如被删除题目以0分计,无效引用的题目提示错误信息。
总的来说,这个答题程序在答题判题程序-2的基础上,进一步增加了对用户信息的处理、对删除题目的处理以及对更多错误情况的处理,使得程序的逻辑更加复杂,对输入数据的处理要求更高,同时也增加了程序的健壮性和用户体验。
类和对象设计
Quiz 类:
属性:题目编号(id)、题目描述(description)、标准答案(solution)。
方法:
构造函数:初始化题目的属性。
matchAnswer:判断给定的答案是否与标准答案匹配。
TestPaper 类:
属性:试卷编号(paperId)、题目分数映射(quizScores)、总分(totalScore)。
方法:
构造函数:初始化试卷的属性。
addQuiz:向试卷中添加题目及其分数。
checkTotalScore:检查试卷的总分是否为100分,并在不是100分的情况下打印警告信息。
ExamSet 类:
属性:题目集合(quizzes)、试卷集合(testPapers)、学生集合(students)、被删除的题目集合(deletedQuizzes)。
方法:
addQuiz:向考试系统中添加一个新的题目。
addTestPaper:向考试系统中添加一张新的试卷。
addStudent:向考试系统中添加一个新的学生。
deleteQuiz:标记一个题目为已删除。
validateAndScoreAnswer:验证给定试卷编号和学生ID的答案,并计算得分。
Main 类:
主程序流程,包括输入处理、题目信息处理、试卷信息处理、学生信息处理、删除题目信息处理、答卷信息处理。
主程序流程
输入处理:
使用 Scanner 类读取控制台输入。
收集所有输入,直到遇到 "end" 标记。
处理题目信息:
解析输入的题目信息,并将其存储在 ExamSet 的 quizzes 映射中。
处理试卷信息:
解析输入的试卷信息,并创建 TestPaper 对象,将其存储在 ExamSet 的 testPapers 映射中。
处理学生信息:
解析输入的学生信息,并将其存储在 ExamSet 的 students 映射中。
处理删除题目信息:
解析输入的删除题目信息,并更新 ExamSet 的 deletedQuizzes 集合。
处理答卷信息:
解析输入的答卷信息,使用 ExamSet 的 validateAndScoreAnswer 方法来验证答案并计算得分。
输出结果:
输出每个问题的题目内容、学生的答案和判题结果。
输出每个试卷的总分警示(如果总分不是100分)。
输出判分信息。
心得
数据结构的选择:
使用 HashMap 和 LinkedHashMap 来存储题目、试卷和学生信息,因为它们提供了快速的查找性能和保持插入顺序的能力。
输入验证:
代码中包含了对输入数据的验证,确保数据的格式和类型正确。这是非常重要的,因为它可以防止程序在运行时出现错误。
测试:
应该编写测试用例来覆盖各种输入情况,包括边界情况和异常情况,确保程序的健壮性。
处理混合输入:
程序能够处理混合输入,即题目信息、试卷信息、学生信息、删除题目信息和答卷信息可能以任意顺序输入。这要求程序在处理输入时具有一定的灵活性和鲁棒性。
处理缺失答案和删除题目:
程序能够正确处理缺失答案和删除题目的情况,对于没有输入答案的题目和被删除的题目计0分。这体现了程序的健壮性。
通过这个答题程序的设计和实现,我们可以学习到如何设计一个接收和处理输入、输出特定结果的系统,并且了解到如何通过面向对象的方法来组织和管理复杂的数据和功能。此外,这个程序也展示了如何使用 Java 的标准库中的类和方法来实现具体的功能。

3.踩坑心得
1.在第三次实验的第二题中出现测试点未过的情况,通过修改判断输入,添加正则表达式来判断输入日期非法

在处理用户输入时,尤其是涉及到特定格式的数据(如日期),使用正则表达式进行验证是一种非常有效的方法。正则表达式可以确保输入符合预期的格式,从而避免程序在后续处理中出现错误。例如,对于日期,可以设计一个正则表达式来匹配“年-月-日”的格式,并确保年、月、日的数值在合理范围内正则表达式是处理格式验证的强大工具,但需要正确编写和应用。在设计输入验证时,应考虑所有可能的非法输入情况,并确保程序能够优雅地处理这些情况。

2.在第二次实验的最后一题中,在进行样例5的测试时,未能通过乱序输入,通过修改TreeMap为HashMap,以及增加了一个方法getAnswerForQuiz()来根据题目ID从答案列表中查找答案。当输入数据的顺序不是预先定义好的顺序时,使用 HashMap 而不是 TreeMap 可以提高查找效率。HashMap 提供了更快的查找速度,因为它不依赖于键的顺序。在处理乱序输入时,选择合适的数据结构是关键。HashMap 在这种情况下通常比 TreeMap 更高效。封装方法(如 getAnswerForQuiz)可以提高代码的可读性和可维护性。

未修改之前测试输入样例

输出为
2+2=5false
3+2=22false
0 0~0
而修改之后输出为
3+2=5true
2+2=22false
70 0~70
3.在第三次作业第三题中的测试样例6时,未能将答案没有输入的优先级最高,导致输出错误,输入

输出
wrong format:#N:1 +1= #A:2
alert: full score of test paper1 is not 100 points
non-existent question~0
the question 2 invalid~0
20201103 Tom: 0 0~0
修改后输出
wrong format:#N:1 +1= #A:2
alert: full score of test paper1 is not 100 points
non-existent question~0
answer is null
20201103 Tom: 0 0~0
修改代码将String answer = i < answers.size() ? answers.get(i) : "answer is null"修改为了String answer = i < answers.size() ? answers.get(i) : ""; 并且在后面的处理中,如果 answer 为空字符串,则会添加结果 "answer is null" 并给0分,此修改将答案没有输入的优先级设置为最高。在处理答案输入时,确保未输入的答案具有最高优先级是非常重要的。这可以通过在代码中正确处理空答案来实现。在设计程序时,应明确各种输入情况的优先级,并在代码中相应地处理。单元测试是确保代码按预期工作的重要步骤,特别是在处理复杂逻辑时。
4.数据类型转换错误
在处理输入时,可能会遇到数据类型转换错误,如将字符串转换为整数时输入的不是数字。在处理数组或集合时,可能会遇到越界错误,尤其是在用户输入不符合预期时。异常处理:用户输入可能会导致程序异常,如 NullPointerException 或 ArrayIndexOutOfBoundsException。在编写代码时,应考虑到所有可能的异常情况,并添加适当的异常处理逻辑。
单元测试和集成测试是确保代码质量的重要手段,代码的可读性和可维护性同样重要,良好的代码结构和注释可以减少未来维护的成本。

4.改进建议

  1. 使用正则表达式判断输入格式
    在答题判断程序3中出现大量错误格式的信息,无效的题目引用输入样例的答案错误,如果用正则表达式判断输入格式能解决。
  2. 异常处理
    在处理输入时,添加适当的异常处理,以防止程序因输入格式错误而崩溃。
    使用try-catch块处理其他可能的异常。
  3. 逻辑分离
    将输入收集、处理和显示逻辑分离,使代码更模块化。
    提供更详细的错误处理和日志记录。
  4. 代码优化
    减少重复代码,使用抽象类或接口。
    使用 Optional 类处理空值。
  5. 性能优化
    使用高效的数据结构,如 TreeMap 而不是 LinkedHashMap 以提高性能。

5.总结
本阶段的三次题目集的最后一题围绕设计和实现一个答题程序展开,并逐步增加了功能的复杂性和多样性。通过设计和实现类,加深了对面向对象编程的理解。学会了如何使用HashMap和List等数据结构来存储和管理题目、答案和判题结果。在处理用户输入,包括解析输入格式和输出格式时学习使用了正则表达式等等,加强了我对代码的理解。学习了如何检测和处理各种错误情况,如格式错误、无效引用等。需要进一步学习及研究的地方也是存在不少如异常处理,在实际应用中,需要更全面地处理异常情况,例如输入数据的验证和错误处理,以及理解输入样例以及题目的意思,最重要的是将代码整合使用。总体来说,本阶段的题目集给我提供了一个很好的机会,通过逐步增加功能的复杂性,帮助我逐步建立起对设计的全面理解。通过进一步学习和实践,来提升自己的编程技能,并为将来的软件开发工作做好准备。

posted on 2024-10-26 21:54  余明凯  阅读(11)  评论(0编辑  收藏  举报

导航