pta答题判断程序总结blog

news/2025/3/15 21:10:01/文章来源:https://www.cnblogs.com/psy-nchu/p/18504388

一、前言
本次blog是针对发布题目集1~3的的最后一题的总结。三次大作业都是模拟一个小型的在线测试系统,先由大作业1完成基本功能,后面进行迭代,不断增加功能,丰富功能。下面具体分析这三次大作业的关键点和区别。
1、答题程序-1
1)输入:题目数量:首先输入题目数量。题目信息:按指定格式输入题目和标准答案。答题信息:记录学生的解答,格式约定答案顺序与题目顺序相对应。
2)实现了最基础的答题判题功能,主要输入题目信息和答题信息,并根据题目数量和答案进行判分。题目数量与答题信息的数量必须一致。
3) 关键点:利用正则表达式和字符串的拆分,解析出题目和答题信息。然后对每个题目判断学生的答案是否与标准答案一致,并输出 true 或 false,最后根据判题结果输出答题信息和判分信息。

2、答题程序-2
1)输入:题目信息:输入题目编号、内容和标准答案。试卷信息:增加试卷的编号和题目编号、分值。答卷信息:记录学生的答卷信息,并判分。
2)在程序-1的基础上,增加了试卷的概念。输入的顺序可以打乱,题目信息、试卷信息和答题信息可以混合输入。支持题目编号缺失的情况,程序仍正常处理。
3) 关键点:利用正则表达式和字符串的拆分,解析出题目、答题和试卷的信息。首先检查试卷总分是否为100分,不等于100分则输出警示。对每道题目进行判断,并根据答案输出 true 或 false。支持输出答题信息缺失提示 answer is null。根据每道题的分值计算学生的总分。

3、答题程序-3
1)输入:题目信息:管理题目编号、内容、标准答案。试卷信息:包含题目编号和分值,引用题目必须有效。学生信息:记录学号和姓名,答卷中学号需对应。删除题目信息:支持删除某道题目,并在答卷输出中标明题目失效。答卷信息:记录学生答题和学号。
2)在程序-2的基础上增加了学生信息管理。支持删除题目的功能,处理题目删除后试卷中对应题目失效的情况。增加了多种输入格式的错误提示,增强了系统的健康性。
3) 关键点:利用正则表达式和字符串的拆分,解析出题目、答题、试卷、学生和删除的信息。删除的题目会输出 the question X invalid 并计0分。引用不存在的题目提示 non-existent question。检查试卷总分不等于100分时输出警示。学号不在学生列表中提示学号引用错误,但答题照常输出。如果答卷信息中试卷的编号找不到,则输出”the test paper number does not exist”。输入信息只要不符合格式要求,均输出”wrong format:”+信息内容。如果答案输出时,一道题目同时出现答案不存在、引用错误题号、题目被删除,只提示一种信息,答案不存在的优先级最高。

二、设计分析
设计合理简洁的结构图可以使代码编写变得简便,因此这部分对三次答题程序的结构、变量、方法进行分析,分别画出他们的类图的顺序图。
1、答题程序-1
1)类图

2)顺序图

3)主函数
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

    // 输入题目数量int questionCount = Integer.parseInt(scanner.nextLine().trim());TestPaper testPaper = new TestPaper();// 输入题目内容for (int i = 0; i < questionCount; i++) {String line = scanner.nextLine().trim();String[] parts = line.split(" #");int number = Integer.parseInt(parts[0].replace("#N:", "").trim());String content = parts[1].replace("#Q:", "").trim(); // 去掉"Q:"String standardAnswer = parts[2].replace("#A:", "").trim();testPaper.addQuestion(new Question(number, content, standardAnswer));}// 输入答题信息AnswerSheet answerSheet = new AnswerSheet(testPaper);String answerLine;while (!(answerLine = scanner.nextLine().trim()).equals("end")) {String[] answerParts = answerLine.replace("#A:", "").trim().split(" ");for (String answer : answerParts) {answerSheet.addAnswer(answer);}}// 判题answerSheet.evaluate();// 输出结果answerSheet.printResults();scanner.close();
}

}
先输入题目数量,再输入题目内容,再输入答题信息,输入完成后,调用判题和输出结果函数。

2、答题程序-2
1)类图

2)顺序图

3)主函数
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Agent agent = new Agent(); // 创建题目和试卷的管理类

    while (scanner.hasNextLine()) {String input = scanner.nextLine().trim();if (input.equals("end")) break;if (input.startsWith("#N:")) {agent.Questioninput(input);  // 解析题目输入} else if (input.startsWith("#T:")) {agent.Testinput(input);  // 解析试卷输入} else if (input.startsWith("#S:")) {agent.Answerinput(input);  // 解析答卷输入}}// 对所有答卷进行判题并输出结果agent.printresult();}

}
由于输入较为复杂,相较于答题程序1,将输入部分放在Agent类中,主函数值调用题目、试卷、答卷解析函数,最后调用判题和输出结果函数。

3、答题程序-3
1)类图

2)顺序图

3)主函数
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Agent agent = new Agent();

    while (scanner.hasNextLine()) {String input = scanner.nextLine().trim();if (input.equals("end")) {break;} else if (input.startsWith("#N:")) {agent.parseQuestionInput(input);} else if (input.startsWith("#T:")) {agent.parseTestInput(input);} else if (input.startsWith("#X:")) {agent.parseStudentInput(input);} else if (input.startsWith("#S:")) {agent.parseAnswerInput(input);} else if (input.startsWith("#D:")) {agent.parseDeleteInput(input);}}agent.printResult();
}

}
与答题程序2一样,输出部分放在Agent类中,主函数调用题目、答题、试卷、学生和删除解析函数,调用判题和输出结果函数。

三、踩坑心得
这部分对大作业中遇到的错误进行总结,在第一部分总结的关键点中,有很多编程时容易遇到很多错误。
1、答题程序-1
1)拆分字符串出现问题
情况描述:本题需要解析出题目#N和答题#A,总是不能解析到正确的题目和答题。输入格式非常严格,空格也会影响解析结果。
解决方法:由于为本行输入,所以需要多次用到分隔符split;去除空格的影响,再多次使用trim()。
如:解析题目内容函数如下,多次使用了分隔符和trim(),去除空格影响。
// 输入题目内容
for (int i = 0; i < questionCount; i++) {
String line = scanner.nextLine().trim();
String[] parts = line.split(" #");
int number = Integer.parseInt(parts[0].replace("#N:", "").trim());
String content = parts[1].replace("#Q:", "").trim(); // 去掉"Q:"
String standardAnswer = parts[2].replace("#A:", "").trim();
testPaper.addQuestion(new Question(number, content, standardAnswer));
}
2)题目和答题信息顺序不一致
情况描述:在实现评分功能时,我发现题号顺序和答题顺序不匹配会导致判分出错。例如,题库的题号为 1, 2, 3, 4,而答卷中题目顺序为 3, 2, 1, 4。
解决方法:判断是否正确是,不要按顺序处理,而是根据题号来进行对比。
public Question getQuestionByNumber(int number) {
for (Question question : questions) {
if (question.getNumber() == number) {
return question;
}
}
return null;
}

2、答题程序-2
1)试卷中缺少题目或题号不一致
情况描述:由于本题中,试卷题目缺失,试卷仍然有效,因此需要再答题程序1基础上进行改进。
解决方法:根据题目编号来查找题目,而不按照解析出的顺序,如果出现没有题目的答案,输出提示信息。
public void printresult() {
for (Answer answerSheet : answers) {
Test test = findTest(answerSheet.testNumber);
if (test != null) {
String result = test.grade(answerSheet, questions);
System.out.println(result);
}
}
}

2)各种输入情况出现时,输出顺序出错。
情况描述:乱序输入+分值不足100+两份答卷+答卷缺失部分答案时,当输入

N:3 #Q:3+2= #A:5

N:2 #Q:2+2= #A:4

T:1 3-7 2-6

S:1 #A:5 #A:22

N:1 #Q:1+1= #A:2

T:2 2-5 1-3 3-2

S:2 #A:5 #A:4

end
输出为
alert: full score of test paper1 is not 100 points
3+2=5true
2+2=22false
7 0~7
alert: full score of test paper2 is not 100 points
2+2=5false
1+1=4false
answer is null
0 0 0~0
解决方法:需要格外注重输出的顺序,先将两张试卷的是否满100分情况先输出。作业才能得到预期输出结果。
alert: full score of test paper1 is not 100 points
alert: full score of test paper2 is not 100 points
3+2=5true
2+2=22false
7 0~7
2+2=5false
1+1=4false
answer is null
0 0 0~0

3、答题程序-3
1)无效的试卷引用,需要输出”the test paper number does not exist”
情况描述:当输入

N:1 #Q:1+1= #A:2

T:1 1-5

X:20201103 Tom

S:2 20201103 #A:1-5 #A:2-4

end
结果输出值显示了alert: full score of test paper1 is not 100 points
解决方法:新增试卷号,进行答卷判断是,要根据试卷号进行检查,然后没有该试卷号,要输出提示信息。
public Test findTest(int testNumber) {
for (Test test : tests) {
if (test.testNumber == testNumber) {
return test;
}
}
return null;
}

2)无效的学生引用,学号不在学生列表中提示学号引用错误,但答题照常输出。
举例:输入:

N:1 #Q:1+1= #A:2

T:1 1-5

X:20201106 Tom

S:1 20201103 #A:1-5 #A:2-4

end
预期输出:
alert: full score of test paper1 is not 100 points
1+1=5false
20201103 not found
解决方法:用try...catch捕获,学号不存在时,答题照常输出并进行判题,最后输出提示信息学号不存在。
public void parseStudentInput(String input) {
try {
input = input.substring(3);
String[] studentParts = input.split("-");

        for (String studentInfo : studentParts) {String[] parts = studentInfo.trim().split(" ");if (parts.length == 2) {String studentId = parts[0].trim();String studentName = parts[1].trim();students.put(studentId, studentName);} else {System.out.println("wrong format: " + input);return;}}} catch (Exception e) {System.out.println("wrong format: " + input);}
}

3)如果答案输出时,一道题目同时出现答案不存在、引用错误题号、题目被删除,只提示一种信息,答案不存在的优先级最高。
举例:含错误格式输入、有效删除、无效题目引用信息以及答案没有输入的情况。输入:

N:1 +1= #A:2

N:2 #Q:2+2= #A:4

T:1 1-5 2-8

X:20201103 Tom-20201104 Jack-20201105 Www

S:1 20201103 #A:1-5

D:N-2

end
预期输出:
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
解决方法:新增错误信息集合,并设置错误信息优先级。
4)删除信息等多种复杂情况的输入时,需要注意输出顺序,以及对所有输入信息均要检验,不符合输入的均要输出提示信息。

四、改进建议
三次大作业的答题程序都没有满分,因此程序还有很多问题,还存在很大的进步空间。
1、答题程序-1
需要解决当答题数量小于题目数量情况时,输出错误的问题。
2、答题程序-2
需要优化混合输入的解析顺序,正确捕获需要的信息。在处理各种判断情况时,应该清晰编写判断函数。输出函数。
3、答题程序-2
需要解决无效的学生引用,学号不在学生列表中提示学号引用错误,答题不能照常输出的问题和输出信息优先级。Agent类中方法功能较多,可以考虑增加Student类,将相关代码放入,让整体框架更为简洁。题目涉及删除学生信息,还可以考虑增删改查功能。
总而言之,在通过更多测试样例的前提下,不断清晰整体框架,改进解析输入方法和输出信息方法,之后再考虑向其他功能的改进。

五、总结
java语言程序设计是本学期才开设的课程,所以接触java语法时间较短,完成这三次答题程序的迭代,需要用到很多没有接触的java语句、语法。虽然遇到很多的问题、错误,但也让我学习到了很多东西。最让我印象深刻的便是三次答题程序的输入解析,面对大量的输入信息,正则表达式可以快速帮我们进行匹配,分隔符split可以快速帮我们进行分组,帮助我们提取到正确的输入信息。面对这种大量信息需要处理的程序时,编写时,一定要先将结构划分清楚,明确有哪些类,哪些功能,类与类之间的关系,作业能使编程更加简单。同时,通过这三次大作业,我意识到方法和变量合理、简单命名的重要性。一个简单、一眼知晓函数功能可以让我们梳理代码逻辑、检查代码错误时事半功倍,省事省力。同时,为了代码的健壮性,我们应该在代码中多设置一下输入输出提示,并注意他们的位置,达到既不凌乱又能给人提示的目的。通过这三个复杂的程序设计,我不仅熟悉了正则表达式,也掌握了各种java语法,熟悉了输入输出语句,了解存储结构arrary、arraylist、list等的使用,类的封装、调用规则。总而言之,虽然这三次程序设计难度很大,遇到很多问题,但也让我收获满满。

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

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

相关文章

Windows 资源管理器显示PSD、PDF、AI 等矢量格式缩略图

1、SageThumbs SageThumbs 是一个强大的 shell 扩展,允许使用 Pierre-e Gougelet 的 GFL 3.40 库(XnView Classic、XnView MP 的作者)直接在 Windows 资源管理器中预览大量图像格式。 AI、PS、EPS、PDF 支持# 要为 Adobe Illustrator (ai)、Postscript (ps, eps) 和 Ad…

第一次博客作业

一、前言: 第一个题目集: 知识点: 包括类的定义、属性(成员变量)、方法(成员函数)以及构造函数。 封装:通过私有化数据域并提供公共的访问器(getter)和修改器(setter)来保护对象内部状态。 构造函数:无参构造函数和带参数构造函数的使用。 字符串表示:重写toStrin…

第12题——入门级js

题目网址:https://match.yuanrenxue.cn/match/12解题步骤看流量包和其回显数据。只有一个流量包,那就是只要访问该网址就能获取页面数据。看下请求地址的组成。变量m一看就是base64编码,解码看下原字符串。再尝试访问第二页,看看原字符串组成的规律。比较明了了,原字符串就…

高等数学 7.10常系数线性微分方程组解法举例

在研究某些实际问题时,会遇到由几个微分方程联立起来共同确定几个具有同一自变量的函数的情况。这些联立的微分方程称为微分方程组。 如果微分方程组中的每一个微分方程都是常系数线性微分方程,那么,这种微分方程组就叫做常系数线性微分方程组。 对于常系数线性微分方程组,…

2024-10-26:最长公共后缀查询。用go语言,给定两个字符串数组 wordsContainer 和 wordsQuery,要对每个 wordsQuery[i] 找到一个与其有最长公共后缀的字符串

2024-10-26:最长公共后缀查询。用go语言,给定两个字符串数组 wordsContainer 和 wordsQuery,要对每个 wordsQuery[i] 找到一个与其有最长公共后缀的字符串。如果有多个字符串与 wordsQuery[i] 有相同的最长公共后缀,则返回在 wordsContainer 中最早出现的那个。最后,返回一…

PTA第1~3次大作业分析及总结

一、前言 经过数周的努力,第三次大作业也落下了帷幕,这三次大作业从第一次到第三次难度逐渐递增,需求不断地增加,对于初学JAVA的我无疑是一个巨大的考验。 第一次大作业,主要侧重类的简单设计,老师在最后一题给出了类的参考设计,算是对我们java的一个入门考验,既是考验…

使用spi-gpio-custom模块配置SPI总线

使用spi-gpio-custom模块配置SPI总线来源 https://www.xuzhe.tj.cn/index.php/2023/10/26/spi-gpio-customspi/ 参考专栏 https://www.zhihu.com/column/c_16980846677677096961. 引言 SPI(Serial Peripheral Interface)是一种常见的串行通信协议,广泛应用于微控制器与外部设…

开源化验单智能识别:思通数科AI平台引领医疗数据处理新变革

智能化验单识别系统在医疗数据管理中的应用意义体现在多个方面,包括提高数据录入效率、减少人为错误、优化患者体验,以及为医疗研究提供高质量数据支持。以下是智能化验单识别系统在医疗数据高效管理中的主要应用意义:提升数据录入效率,减轻医护人员负担传统的化验单录入多…

关于栈

关于栈栈的图一.什么是堆栈平衡(比较抽象)含义就是 当函数在一步步执行的时候 一直到ret执行之前,堆栈栈顶的地址 一定要是call指令的下一个地址。 也就是说函数执行前一直到函数执行结束,函数里面的堆栈是要保持不变的。 如果堆栈变化了,那么,要在ret执行前将堆栈恢复成原…

简单谈谈Google TPUv6

简单谈谈Google TPUv6 根据Google TPU第六代的数据做了一些性能数据的对比,需要注意的是TPUv6当前应该是一个用于训推一体的单Die的版本,用于训练的V6p双Die版本应该会后期再发布. 需要注意的是在国内外都开始卷大模型推理价格的时候, TPU这样的东西对于提高ROI非常有帮助。快…