题目集1~3的总结性Blog

news/2025/3/15 17:51:40/文章来源:https://www.cnblogs.com/bangksm/p/18504487

一、前言

     相关知识点:

     1、第一次题目集主要是对java的类的设计以及相关的方法的使用,包括数组的使用方法,类和对象的使用等进行考察。

     2、第二次题目集则是对第一次题目集的一次强化以及补充,要求掌握排序以及查找相关方法的使用,以及对于类与对象的概念进行了强调。

     3、第三次题目集对类的封装以及日期类的基本使用进行了考察。每一次的题目的完成都比上一次更加的困难,知识点由浅入深慢慢的提升我们的编程思维。

     题量:

     三次题目集的题目量分别为5+4+3,第一次对基本的类与方法的使用做出了要求,之后每次都在上一次增加难度循序渐进。

     难度:

     三次题目集的难度是直线上升的,尤其体现在每次题目及最后的答题判断程序的设计上,后面两次每一次都建立在上一次的基础上,但是在做出修改时还是很困难。

二、设计与分析

   1、答题判断程序-1

根据题意设计实现答题程序,模拟一个小型的测试,要求输入题目信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。

题目中的输入分为三个部分题目数量、题目内容以及答题信息,最后以输入的end结尾,对题目进行分析,根据输入的格式则是首先根据输入的“#”来进行分割再根据“:”

来进行分割后将题目以及标准答案的内容放入数组中,之后在答案部分再以“#A”为起始,根据“ ”来进行分割。然后再将判断答案是否与标准答案相同,之后再进行输出。

题目要求将信息分为三个类,1、题目类(用于封装单个题目的信息)2、试卷类(用于封装整套题目的信息)3、答卷类(用于封装答题信息)。由此设计出

   

 

           以上三个类以及调用他们的Main函数。

 

public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int questionCount = Integer.parseInt(scanner.nextLine().trim());Paper paper = new Paper();for (int i = 0; i < questionCount; i++) {String line = scanner.nextLine().trim();String[] parts = line.split("#"); // 使用 # 进行分割int number = Integer.parseInt(parts[1].split(":")[1].trim());String content = parts[2].split(":")[1].trim(); // 题目内容String standardAnswer = parts[3].split(":")[1].trim(); // 标准答案paper.addQuestion(new Question(number, content, standardAnswer));}AnswerSheet answerSheet = new AnswerSheet(paper);String answerLine;while (!(answerLine = scanner.nextLine().trim()).equals("end")) {String[] answerParts = answerLine.split(" "); // 根据空格分割for (String answer : answerParts) {if (answer.startsWith("#A:")) {answerSheet.addAnswer(answer.substring(3).trim()); // 移除 #A:
                }}}answerSheet.checkAnswers();answerSheet.printResults();}
}

 

其中AnsewerSheet类中包含了最后答卷的输出,再Main中调用answerSheet.printResult();来将结果显示出来。

SourceMonitor分析如下:

 

 

         2、答题判断程序-2

在答题判断程序-1上做出了修改,以1为基础新增了试卷信息的输入且输入信息的顺序被打乱,因此1中的判断程序必须重新修改以确保正确的输出

且在输入不正确时多了更多的报错,现阶段输入信息分为三类

1、题目信息

 

   一行为一道题,可输入多行数据(多道题)。

 

   格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案

2、试卷信息

一行为一张试卷,可输入多行数据(多张卷)。

格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值

3、答卷信息

    答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序与试卷信息中的题目顺序相对应。

   格式:"#S:"+试卷号+" "+"#A:"+答案内容

根据输入时以"#N"、"#T"、"#S"开头来判断输入的是以上三种信息的哪一种,并将其存入相应的数组中

实现代码:

 

            if (input.startsWith("#N:")) {String[] parts = input.split(" ");int number = Integer.parseInt(parts[0].substring(3));String content = parts[1].substring(3);String answer = parts[2].substring(3);questions.put(number, new Question(number, content, answer));}else if (input.startsWith("#S:")) {String[] parts = input.split(" ");int testPaperNumber = Integer.parseInt(parts[0].substring(3));List<String> answers = new ArrayList<>();for (int i = 1; i < parts.length; i++) {answers.add(parts[i].substring(3));}answerSheets.add(new answerPaperSheet(testPaperNumber, answers));}else if (input.startsWith("#T:")) {String[] parts = input.split(" ");int testPaperNumber = Integer.parseInt(parts[0].substring(3));TestPaper testPaper = new TestPaper(testPaperNumber);for (int i = 1; i < parts.length; i++) {String[] questionScore = parts[i].split("-");int questionNumber = Integer.parseInt(questionScore[0]);int score = Integer.parseInt(questionScore[1]);testPaper.addQuestion(questionNumber, score);}testPapers.put(testPaperNumber, testPaper);if (testPaper.TotalScore() != 100) {addPapers.add(testPaperNumber);}}

 

在答题判断程序-1的基础上三个类也做出了相应的改变,以下是类图

延续了答题判断程序-1的三个类并对其做出了更改在此次的程序中加入了哈希表的应用。由于在完成时遇到了许多问题所以将许多东西都已到了Main中

因此Main函数的代码过多此处则选择性的选出一部分。以下为当输入错误时以及相关的错误时以及各种输出的时候所需要的代码

       for (int paperNumber : addPapers) {System.out.println("alert: full score of test paper" + paperNumber + " is not 100 points");}for (answerPaperSheet sheet : answerSheets) {if (!testPapers.containsKey(sheet.testPaperNumber)) {System.out.println("The test paper number does not exist");continue;}TestPaper paper = testPapers.get(sheet.testPaperNumber);List<String> results = new ArrayList<>();List<Integer> scores = new ArrayList<>();int totalScore = 0;int allAnswer = 0;for (int questionNumber : paper.questionScores.keySet()) {int score = paper.questionScores.get(questionNumber);String giveAnswer = allAnswer < sheet.answers.size() ? sheet.answers.get(allAnswer) : null;Question question = questions.get(questionNumber);if (question != null) {if (giveAnswer == null) {results.add("answer is null");scores.add(0);} else {boolean right = question.answer.equals(giveAnswer);results.add(question.content + "~" + giveAnswer + "~" + (right ? "true" : "false"));scores.add(right ? score : 0);}} else {results.add("answer is null");scores.add(0);}totalScore += scores.get(scores.size() - 1);allAnswer++;}for (String result : results) {System.out.println(result);}System.out.println(String.join(" ", scores.stream().map(String::valueOf).toArray(String[]::new)) + "~" + totalScore);}

用于判断试卷满分是否为100分以及输入的答案是否与标准答案相同,以及输入的试卷号是否存在等。

SourceMonitor分析如下:

 

   3、答题判断程序-3

与前两次的程序相比第三次的答题判断程序加入了更多的输入信息前两次的输入都为三种信息在本次的答题判断程序中则变为了五种

新增了学生信息以及删除题目信息以下为新增两种信息的格式

 

1、学生信息

 

  学生信息只输入一行,一行中包括所有学生的信息,每个学生的信息包括学号和姓名,格式如下。

 

格式:"#X:"+学号+" "+姓名+"-"+学号+" "+姓名....+"-"+学号+" "+姓名

2、删除题目信息

  删除题目信息为独行输入,每一行为一条删除信息,多条删除信息可分多行输入。该信息用于删除一道题目信息,题目被删除之后,引用该题目的试卷依然有效,但被删除的题目将以0分计,同时在输出答案时,题目内容与答案改为一条失效提示,例如:”the question 2 invalid~0”

格式:"#D:N-"+题目号

错误提示也新增了被删除的题目提示信息当某题目被试卷引用,同时被删除时,答案中输出提示信息以及题目引用错误提示信息试卷错误地引用了一道不存在题号的试题,在输出学生答案时,提示”non-existent question~”加答案。因此在需要增加的判断函数也增加了,以及答题判断程序-2中的三个类也必须做出相对应的改变才行

以下为更改后的类图:

 在AnswerPaperSheet类中加入了studentid以及AnswerPaperSheet()函数中加入了String studentid以便后续对学生信息的处理

在Main函数中则根据输入的信息的开头以"#N:"、"#T:"、"#X:"、"#S:"、"#D:N-"中的某一个开头来进行判断输入的为何种信息。

并进行对应的报错。

            if (input.startsWith("#N:")) {String[] parts = input.split(" ");if (parts.length != 3 || !parts[0].startsWith("#N:") || !parts[1].startsWith("#Q:") || !parts[2].startsWith("#A:")) {System.out.println("wrong format:" + input);continue;}try {int number = Integer.parseInt(parts[0].substring(3));String content = parts[1].substring(3);String answer = parts[2].substring(3);questions.put(number, new Question(number, content, answer));} catch (Exception e) {System.out.println("wrong format:" + input);}}else if (input.startsWith("#T:")) {String[] parts = input.split(" ");if (parts.length < 2 || !parts[0].startsWith("#T:")) {System.out.println("wrong format:" + input);continue;}try {int testPaperNumber = Integer.parseInt(parts[0].substring(3));TestPaper testPaper = new TestPaper(testPaperNumber);for (int i = 1; i < parts.length; i++) {String[] questionScore = parts[i].split("-");int questionNumber = Integer.parseInt(questionScore[0]);int score = Integer.parseInt(questionScore[1]);testPaper.addQuestion(questionNumber, score);}testPapers.put(testPaperNumber, testPaper);if (testPaper.totalScore() != 100) {invalidTestPapers.add(testPaperNumber);}} catch (Exception e) {System.out.println("wrong format:" + input);}}else if (input.startsWith("#X:")) {String[] parts = input.substring(3).split("-");for (String part : parts) {String[] studentInfo = part.split(" ");if (studentInfo.length == 2) {students.put(studentInfo[0], studentInfo[1]);} else {System.out.println("wrong format:" + input);break;}}}else if (input.startsWith("#S:")) {String[] parts = input.split(" ");if (parts.length < 3 || !parts[0].startsWith("#S:") || !students.containsKey(parts[1])) {System.out.println("wrong format:" + input);continue;}try {int testPaperNumber = Integer.parseInt(parts[0].substring(3));String studentId = parts[1];List<String> answers = new ArrayList<>();for (int i = 2; i < parts.length; i++) {String[] answerParts = parts[i].split("-");if (answerParts.length == 2) {answers.add(answerParts[1].trim());} else {System.out.println("wrong format:" + input);break;}}answerSheets.add(new AnswerPaperSheet(testPaperNumber, studentId, answers));} catch (Exception e) {System.out.println("wrong format:" + input);}}else if (input.startsWith("#D:N-")) {try {int questionNumber = Integer.parseInt(input.substring(5));deletedQuestions.add(questionNumber);} catch (Exception e) {System.out.println("wrong format:" + input);}} else {System.out.println("wrong format:" + input);}}

Main函数的主体与答题判断程序-2的大致相同,但是新增了更多的报错以及输出。

SourceMonitor分析如下:

三、踩坑心得

 

1、首先便是我已经不知道第多少次忘记的在PTA中只能用Main来写主方法,在IDEA上还能好好运行一到PTA上就出现了以下报错,

将主函数名改为Main即可。

2、没有注意到输出的格式随意编写输出导致输出的格式不符合,导致测试点全错。

 更改后:

 

3.输出顺序的注重:

输出的顺序应该是:

(1) 判断输入的试卷的总分是否是100分,如若不是,则输出:alert:fullscoreoftestpaperisnot100points。

(2) 判断答卷是否有对应的试卷,如果没有,则输出:Thetestpapernumberdoesnotexist。如果存在则输出每道题的内容以及对应的结果。如果输入的答案信息少于试卷的题目数量,缺失答案的题目输出"answerisnull" 。如果题目被删除,则输出0

(3) 输出学号+""+姓名+": "+题目得分+""+....+题目得分+"~"+总分

在输出每张答卷时及情况时要主要顺序:

错误案例:

代码中只是简单地设置了标志符,判断是否存在答卷是否有对应地试卷,并没有考虑到输出每张答卷时要注意顺序,造成输出结果的错误和混乱。

输入样例:

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

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

#T:13-72-6

#S:3#A:5#A:22

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

#T:22-51-33-2

#S:2#A:5#A:4

End

正确输出结果:

alert:full score of test paper1 is not 100 points

alert:full score of test paper2 is not 100 points

The test paper number does not exist

2+2=5false

1+1=4false

Answer is null

000~0

错误输出结果:

alert:full score of test paper1 is not 100 points

alert:full score of test paper2 is not 100 points

2+2=5false

1+1=4false

Answer is null

000~0

The test paper number does not exist

所以当写程序时,要着重注意输出的顺序。

四、改进建议

1. 异常处理
在解析输入时添加异常处理,确保程序在遇到无效输入时能够优雅地处理,而不是直接崩溃。例如,可以捕获 NumberFormatException。

2. 输入解析方法
将输入解析部分提取成单独的方法,增强代码的可读性和可维护性。

3. 改进 printResults 方法
在打印结果时,可以使用 StringBuilder 来构建输出,减少多次调用 System.out.print 带来的性能损耗。

4. 使用常量
对于常量字符串(如 "#A:"),可以考虑使用常量字段,增加代码的可读性和维护性。

5. 主程序逻辑简化
主程序逻辑可以分成多个小函数,减少 main 方法的复杂度。

6. 代码注释
适当添加注释,尤其是在复杂逻辑的地方,能够帮助未来的维护者更快理解代码。

五、总结

这三次Java作业的主要任务是实现一个简单的问答系统,包括题目管理、答案录入以及结果评估功能。系统通过命令行界面与用户交互,用户可以输入题目和标准答案,然后录入自己的答案并获取结果。本次作业加深了对面向对象设计的理解,特别是如何通过类与对象封装数据和行为。本次作业特别强调了相关类的书写而且用过本次作业学习了正则表达式的用法,对以后代码的书写提供了便利。还学习到了如何通过重构提升代码的质量,注重代码的可读性和可维护性。

经过这三次的java大作业我对我自己水平的不足有了深刻的认识,在许多地方都一知半解,导致每次都没法完整的完成作业,在之后我会花费更多的时间去练习java程序的编写。

 

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

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

相关文章

java一阶段作业总结

前言第一次题目集主要学习了类和对象的基本使用,主要训练了对构造方法,私有公共属性,对象的封装的能力,建立起了基本的类的概念,题量正常,最后一题的设计建议十分有用!!!(我自己刚开始建会乱七八糟,但是有了这个框架建议后面每次迭代改进都可以照葫芦画瓢)第二次题…

C# DataGridView 禁用或灰显单元格 只读 清除单元格选择

1. 清除单元格选择 DataGridView.ClearSelection();效果2.单元格灰显 // 单元格设为只读 DataGridView.ReadOnly = true; // 表格背景色 DataGridView.BackgroundColor = SystemColors::Control; // 标题栏背景色 DataGridView.ColumnHeadersDefaultCellStyle.BackColor = Syst…

博图SCL编程计算近一小时测量值的均值

这一篇学习笔记在新浪记录过,这里再次记录一次。 1. 打开上午的博图程序,新建一个FB块,设置变量参数。2. 该FB块新建SCL程序段,写下面的程序3. 在OB30循环中断组织块添加一个程序段,调用FB1,添加背景数据块,给输入和输出连接变量。对于新建的FB,刚刚运行时,由于数据量…

JavaScript CSS Vue3 实现一个简单的Loading

之前项目用到的,后来换其他效果了。放博客里保存一下。 效果 视频转GIF之后不太流畅……代码 <script setup lang="ts">import {onBeforeUnmount, onMounted, ref} from "vue"; import {clamp} from "../scripts/Utils";const maskDiv = …

Metasploit被控端与主控端的使用

Metasploit被控端与主控端的使用 确认IP地址 首先我们先查看一下攻击机和靶机的ip地址 攻击机ip:192.168.126.129靶机IP:125.217.53.83ps:后面电脑重启了,ip不一定对的上生成被控端 我们先使用输入msfvenom命令生成一个payload,这是以下参数的解释: -p:使用反向远程控制程…

03 布尔逻辑与逻辑门

晶体管二进制,只显示两种信号状态,电路连接为真,电路断开为假,成千上万的晶体管中同时多状态容易出错 布尔提出逻辑运算:输入真与假,对输入进行not,and,or的运算,产生输出 晶体管控制线通电,将控制线作为input,来电一极连接导出线作为output,控制线通电on电流可以从…

TRLO: An Efficient LiDAR Odometry with 3D Dynamic Object Tracking and Removal

arxiv | 中科院联合国科大开源 TRLO:一种结合3D动态物体跟踪与移除的高效LiDAR里程计 【TRLO: An Efficient LiDAR Odometry with 3D Dynamic Object Tracking and Removal】 文章链接:[2410.13240] TRLO: An Efficient LiDAR Odometry wit...项目主页:GitHub - Yaepiii/TRL…

只需初中数学知识就能理解人工智能大语言模型

全面解释人工智能LLM模型的真实工作原理(一) 人工智能 #大语言模型LLM #机器学习ML #深度学习 #数据挖掘序言:为了帮助更多人理解,我们将分成若干小节来讲解大型语言模型(LLM)的真实工作原理,从零开始,不需额外知识储备,只需初中数学基础(懂加法和乘法就行)。本文包…

实验3 c语言函数应用编程

实验任务1 task1.c1 #include <stdio.h>2 3 char score_to_grade(int score); // 函数声明4 5 int main() {6 int score;7 char grade;8 9 while(scanf("%d", &score) != EOF) { 10 grade = score_to_grade(score); // 函数调用 11 …

Mit6.S081笔记Lab3: page tables 页表

课程地址:https://pdos.csail.mit.edu/6.S081/2020/schedule.html Lab 地址:https://pdos.csail.mit.edu/6.S081/2020/labs/pgtbl.html 我的代码地址:https://github.com/Amroning/MIT6.S081/tree/pgtbl 相关翻译:http://xv6.dgs.zone/labs/requirements/lab3.html 参考博客…

java 为什么有private关键字_2

在讨论编程语言设计时,Java语言中的`private`关键字扮演着至关重要的角色。私有访问修饰符`private`的主要目的是封装、数据隐藏。通过限制对类成员的访问,它确保了对象的内部状态不能被外部代码随意修改,从而保护了对象的完整性和一致性。这种封装机制是面向对象编程(OOP)…

为什么有开源社区版,还有那么多公司使用专业版-谈HPC调度器

开放源码与商用 HPC 工作负载管理器的成本效益比较 商用高性能计算机工作负载管理器 1 简介 高性能计算(HPC High-performance computing)为多个行业的科学发现和创新提供了动力。大型数据集、先进的仿真技术和机器学习的结合,帮助企业产生了没有现代 HPC 基础设施就无法实现…