Blog1-3
Blog 1-3总结
1.前言
三个礼拜左右的pta训练,让我成功认知到了学校对java这门课程的重视。
总体而言,这三次pta难度都是比较大的,让我的头发掉了一根又一根,而且题目难度跨度太大了,让人有点难以适应,也是因为难度跨度很大,导致分数的分配也不是很均匀。还有就是有些测试点真的有点奇怪,让我苦苦思索了很久,改了一遍又一遍。
最后就是关于知识点方面了,题目集涵盖了正则表达式、列表、泛型和类间关系等等。正则表达式用于文本匹配和验证;列表是有序数据集合,支持增删改查操作;泛型增加代码灵活性,允许类或方法在不同类型上工作;类间关系包括继承、实现、关联、聚合和组合,描述了类之间的连接和交互。
2.设计与分析
答题判题程序-1
题目与源码分析
该代码的对象,类及类间关系
对象:
Main: 主类,包含程序的入口点,负责调用输入处理和输出处理的方法。
DealInput: 处理输入的类,负责读取用户输入的题目和答案,并进行相应的处理。
DealOutput: 处理输出的类,负责生成和输出结果。
TiMu: 表示题目的类,包含题号、题目内容和正确答案。
类及类间关系:
Main与DealInput之间的关系:Main类通过创建DealInput对象来调用处理输入的方法,从而完成输入的处理。
Main与DealOutput之间的关系:Main类通过创建DealOutput对象来调用处理输出的方法,从而完成输出的处理。
DealInput与TiMu之间的关系:DealInput类使用TiMu类来表示题目,DealInput类包含一个ArrayList<TiMu>来存储题目列表。
DealOutput与DealInput之间的关系:DealOutput类使用DealInput类来获取处理好的题目和答案,然后生成相应的输出结果。
DealOutput与TiMu之间的关系:DealOutput类使用TiMu类来获取题目的内容和正确答案,以便生成输出结果。
以下为源码:
import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class Main { //判题程序 static Scanner scanner = new Scanner(System.in); public static void main(String[] args) { int n = scanner.nextInt();//题目数量 scanner.nextLine(); dealInput dealInput = new dealInput(); dealInput.deal_input_tihao_timu(n); dealInput.deal_input_zuodaArea(); dealInput.deal_input_end(); dealOutput dealOutput = new dealOutput(); dealOutput.deal_output_ans(n, dealInput); dealOutput.output_judge(n); } } class dealInput{ TiMu tiMu; ArrayList<TiMu> list; ArrayList<String> zuoda_list; public dealInput() { list = new ArrayList<TiMu>(); zuoda_list = new ArrayList<String>(); } public void deal_input_tihao_timu(int n) { for (int i = 0; i < n; i++) { String str = Main.scanner.nextLine(); String[] arr = str.split("#"); int q = 0, w = 0; for(int j = 2;j < arr[1].length();j++){ if(arr[1].charAt(j) != ' '){ q = j; for(int k = arr[1].length() - 1;k >= 2;k--){ if(arr[1].charAt(k) != ' '){ w = k + 1; break; } } break; } } String s = arr[1].substring(q, w); int num = Integer.parseInt(s); for(int j = 2;j < arr[2].length();j++){ if(arr[2].charAt(j) != ' '){ q = j; break; } } for(int j = arr[2].length() - 1;j >= 2 ;j--){ if(arr[2].charAt(j) != ' '){ w = j + 1; break; } } String contextString = arr[2].substring(q, w); for(int j = 2;j < arr[3].length();j++){ if(arr[3].charAt(j) != ' '){ q = j; break; } } for(int j = arr[3].length() - 1;j >= 2 ;j--){ if(arr[3].charAt(j) != ' '){ w = j + 1; break; } } String ans = arr[3].substring(q, w); tiMu = new TiMu(num, contextString, ans); list.add(tiMu); } Collections.sort(list); } public void deal_input_zuodaArea() { String str = Main.scanner.nextLine(); String[] arr = str.split("#"); for(int i = 1;i < arr.length;i++){ String s = arr[i]; int q = 0, w = 0; for(int j = 2;j < s.length();j++){ if(s.charAt(j) != ' '){ q = j; for(int k = s.length() - 1;k>=2;k--){ if(s.charAt(k) != ' '){ w = k + 1; break; } } break; } } String ans = arr[i].substring(q, w); zuoda_list.add(ans); } } public void deal_input_end() { String input; while (true) { input = Main.scanner.nextLine(); if (input.equals("end")) { break; } } } } class dealOutput{ dealInput dealInput; ArrayList<Integer> ansList; ArrayList<String> judgeList; public dealOutput() { ansList = new ArrayList<Integer>(); judgeList = new ArrayList<String>(); } public void deal_output_ans(int n,dealInput dealInput) { ArrayList<TiMu> tiMusList = dealInput.list; ArrayList<String> asList = dealInput.zuoda_list; for (int i = 0; i < n; i++) { String suanShi_ans = tiMusList.get(i).getContext()+"~"; System.out.println(suanShi_ans + asList.get(i)); //System.out.println(suanShi_ans); } for (int i = 0; i < n; i++) { String ans_zuoda = tiMusList.get(i).getAns(); if (ans_zuoda.equals(asList.get(i))) { String s = "true"; judgeList.add(s); }else { String s = "false"; judgeList.add(s); } } } public void output_judge(int n) { for (int i = 0; i < n; i++) { if(i!=n-1) { System.out.print(judgeList.get(i)+" "); }else { System.out.print(judgeList.get(i)); } } } } class TiMu implements Comparable<TiMu>{ private int num; private String context; private String ans; public TiMu(int num,String contextString,String ans) { this.num = num; this.context = contextString; this.ans = ans; } @Override public String toString() { return "题号: " + num + ", 题目内容: " + context + ", 答案: " + ans; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getContext() { return context; } public void setContext(String context) { this.context = context; } public String getAns() { return ans; } public void setAns(String ans) { this.ans = ans; } @Override public int compareTo(TiMu o) { // TODO Auto-generated method stub return Integer.compare(this.num, o.num); } }
程序流程:
输入阶段:
主类Main的main方法首先被执行,程序开始运行。
从标准输入中读取一个整数n,表示题目的数量。
创建DealInput对象dealInput。
调用dealInput对象的dealInputTihaoTimu方法,处理题目和答案的输入。
循环读取n行题目信息,每行包含题号、题目内容和正确答案,将其封装成TiMu对象,并按题号排序后存储到题目列表中。
调用dealInput对象的dealInputZuodaArea方法,处理左答区的输入。
读取一行左答区的信息,将其中的答案依次存储到答案列表中。
调用dealInput对象的dealInputEnd方法,处理输入结束的标志。
循环读取输入,直到遇到"end"为止。
处理输出:
创建DealOutput对象dealOutput。
调用dealOutput对象的dealOutputAns方法,处理输出结果。
遍历题目列表和答案列表,依次输出题目内容和左答区的对应答案。
比较题目的正确答案和左答区的答案,生成判断结果,并存储到判断结果列表中。
调用dealOutput对象的outputJudge方法,输出最终的判断结果。
遍历判断结果列表,将结果按要求输出到标准输出。
程序结束:
整个程序执行完成,结束运行。
解题心得:
模块化设计:将程序分成输入处理、输出处理和主控制流程模块,有助于代码组织和维护。
数据结构选择:使用ArrayList存储题目和答案,TiMu类表示题目,简化管理和操作。
算法思路:通过循环遍历题目和答案列表,比对左答区和正确答案,得出判断结果并输出。
错误处理:考虑用户可能的错误输入,如负数题目数量或空题目内容,添加适当的错误处理和提示。
代码风格和规范:保持良好的代码风格和命名规范,添加注释和文档说明,提高代码可读性和可维护性。
答题判题程序-2
题目与源码分析
该代码的对象,类及类间关系:
Question(题目):
属性:题目编号(number)、内容(content)、答案(answer)
方法:构造函数、getter和setter方法
TestPaper(试卷):
属性:试卷编号(number)、题目编号列表(questionNumbers)、题目分数列表(questionScores)、是否满分(is100)
方法:构造函数、添加题目及分数方法(addQuestionScore)、设置是否满分方法(setIs100)
AnswerSheet(答题卡):
属性:试卷编号(testPaperNumber)、答案列表(answers)
方法:构造函数、添加答案方法(addAnswer)
Main(主程序):
主要负责解析输入,构建题目、试卷和答题卡对象,以及计算得分和输出结果。
这些类之间的关系如下:
TestPaper类包含多个Question对象,表示试卷包含多道题目。
AnswerSheet类与TestPaper类相关联,每个AnswerSheet对象对应一个TestPaper对象。
Main类协调整个程序的执行过程,负责输入解析、对象构建、得分计算和结果输出。
以下为源码:
import java.util.*; class Question { String number; String content; String answer; public Question(String number, String content, String answer) { this.number = number; this.content = content; this.answer = answer; } } class TestPaper { String number; Boolean is100; List<String> questionNumbers; List<Integer> questionScores; int size; public TestPaper(String number) { this.number = number; this.questionScores = new ArrayList<>(); this.questionNumbers = new ArrayList<>(); this.size = 0; } public void addQuestionScore(String questionNumber, int score) { questionNumbers.add(questionNumber); questionScores.add(score); size++; } public void setIs100(){ int sum = 0; for(int i = 0;i<size;i++){ sum += questionScores.get(i); } is100 = sum == 100; } } class AnswerSheet { String testPaperNumber; List<String> answers; public AnswerSheet(String testPaperNumber) { this.testPaperNumber = testPaperNumber; this.answers = new ArrayList<>(); } public String getTestPaperNumber(){ return testPaperNumber; } public void addAnswer(String answer) { answers.add(answer); } } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Map<String, Question> questions = new HashMap<>(); Map<String, TestPaper> testPapers = new HashMap<>(); List<AnswerSheet> answerSheets = new ArrayList<>(); String input; while (!(input = scanner.nextLine()).equals("end")) { if (input.startsWith("#N:")) { String[] parts = input.split(" "); String number = 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("#T:")) { String[] parts = input.split(" "); String testPaperNumber = parts[0].substring(3); TestPaper testPaper = new TestPaper(testPaperNumber); for (int i = 1; i < parts.length; i++) { String[] questionScore = parts[i].split("-"); testPaper.addQuestionScore(questionScore[0], Integer.parseInt(questionScore[1])); } testPaper.setIs100(); testPapers.put(testPaperNumber, testPaper); } else if (input.startsWith("#S:")) { String[] parts = input.split(" "); String testPaperNumber = parts[0].substring(3); AnswerSheet answerSheet = new AnswerSheet(testPaperNumber); for (int i = 1; i < parts.length; i++) { answerSheet.addAnswer(parts[i].substring(3)); } answerSheets.add(answerSheet); } } // 按照testPaperNumber排序 Collections.sort(answerSheets, Comparator.comparing(AnswerSheet::getTestPaperNumber)); Map<String, Boolean> mp = new HashMap<>(); for (AnswerSheet answerSheet : answerSheets) { TestPaper testPaper = testPapers.get(answerSheet.testPaperNumber); int totalScore = 0; Boolean alert = mp.get(answerSheet.testPaperNumber); if(alert != null){ } else{ if(!testPaper.is100){ alert = true; System.out.println("alert: full score of test paper" + testPaper.number + " is not 100 points"); } mp.put(answerSheet.testPaperNumber, true); } if (testPaper != null) { Boolean p = true; StringBuilder scoreInfo = new StringBuilder(); for (int i = 0; i < answerSheet.answers.size(); i++) { //String questionNumber = testPaper.questionScores.keySet().toArray()[i].toString(); String questionNumber = testPaper.questionNumbers.get(i); int score = testPaper.questionScores.get(i); Question question = questions.get(questionNumber); if (question != null) { String answer = answerSheet.answers.get(i); boolean isCorrect = answer.equals(question.answer); if(p){ if(isCorrect) scoreInfo.append(testPaper.questionScores.get(i)); else scoreInfo.append("0"); p = false; } else{ if(isCorrect) scoreInfo.append(" ").append(testPaper.questionScores.get(i)); else scoreInfo.append(" ").append("0"); } totalScore += isCorrect ? score : 0; System.out.println(question.content + "~" + answer + "~" + isCorrect); } } System.out.println(scoreInfo + "~" + totalScore); } else { System.out.println("The test paper number does not exist"); } } } }
程序流程:
初始化阶段:
创建Scanner对象用于接收用户输入。
创建空的题目、试卷和答题卡对象的容器(Map或List)。
通过循环读取用户输入,解析输入内容,并根据输入内容创建题目、试卷和答题卡对象,并存储到相应的容器中,直到输入结束标志"end"。
得分计算阶段:
对于每个答题卡对象,获取对应的试卷对象。
遍历试卷中的题目,逐一与答题卡中的答案进行比对,计算得分。
如果试卷总分不为100,则输出警告信息。
结果输出阶段:
对于每个答题卡对象,逐一输出每道题目的内容、答案、是否正确,并显示总得分。
程序结束:
关闭Scanner对象。
程序执行完毕。
解题心得:
面向对象设计:代码采用面向对象的设计方式,将题目、试卷和答题卡等实体抽象成对象,使程序结构清晰,易于理解和维护。
模块化开发:将功能模块拆分成不同的类,每个类负责特定的功能,有利于代码复用和维护。例如,题目、试卷和答题卡分别由不同的类来表示和管理。
输入解析:程序能够有效地解析用户输入,根据输入内容动态创建题目、试卷和答题卡对象,这样的设计使程序更加灵活,能够处理不同格式的输入数据。
逻辑清晰:通过主程序的流程分析,可以看出程序的逻辑清晰,按照初始化、得分计算和结果输出的顺序执行,每个阶段的任务明确,易于理解。
错误处理:虽然代码片段并未显示完整的错误处理机制,但在实际应用中,需要考虑到各种可能的错误情况,例如输入格式错误、题目编号重复等,对这些情况进行适当的处理和提示。
答题判题程序-3
题目与源码分析
第三次就会很麻烦,相较于第二次添加了很多内容,就不多说,直接给出解决办法
先要考虑的是处理多种错误报告的优先级。一种常见的方法是定义一个错误代码或类型,并为每种错误分配一个优先级。例如:
1 表示输入格式错误
2 表示引用题目不存在
3 表示引用题目被删除
4 表示答卷无对应题目
5 表示答卷无对应试卷
6 表示学号无对应学生
然后,可以根据这些优先级在程序中处理错误,确保最重要的错误首先被解决。
接下来,让我们来看看类的设计:
题目类(Text):包含题目编号、题目内容和题目答案等属性。
试卷类(Paper):包含试卷编号、试卷内题目编号、题目回答、试卷内总题数、试卷总得分、试卷每题分数等属性。
答卷类(AnswerSheet):包含答卷编号、答卷总数、答卷内答案、得分结果等属性。
删除类(Delete):包含被删除题号等属性。
学生类(Student):包含学生学号和学生姓名等属性。
操作类(Operation):包含所有题目信息、所有试卷信息、所有答卷信息等属性和方法,用于操作题目、试卷和答卷。
在操作类中,你可以设计各种方法来处理输入、检查错误、添加题目、删除题目、生成试卷、批改答卷等功能。同时,你还可以在操作类中实现处理错误报告的逻辑,根据错误优先级逐一处理错误。
对于格式错误,可以设计一个方法来检查输入是否符合规定的格式,如果不符合,则返回错误代码 1;对于其他错误,可以在相应的操作方法中进行检查并返回相应的错误代码。
在类的设计中,要考虑到每个类的属性和方法,确保它们能够满足需求,并且类之间的关系清晰明了,便于代码的编写和维护。
踩坑心得:
1.错误报告的优先级管理:**确保设计一个清晰的错误代码体系,并根据错误的严重程度分配优先级。在处理错误时,要按照优先级逐一解决,确保最重要的错误首先被处理。
2.多种错误同时发生时的处理:**由于一个输入可能同时存在多种错误,因此在处理错误时要考虑到这种情况。可以使用递归或者嵌套的方式来处理多种错误,确保每种错误都得到了适当的处理。
3.输入格式错误的检查:**设计一个严格的输入格式检查机制,确保用户输入的数据符合规定的格式。可以使用正则表达式或者自定义的输入检查函数来实现。
4.异常情况的处理:**在设计类的方法时,要考虑到各种可能的异常情况,并在方法中加入相应的异常处理逻辑,确保程序能够在异常情况下正常运行。
5.类之间的关系管理:**要确保类之间的关系清晰明了,避免出现循环依赖或者过度耦合的情况。可以使用接口、抽象类等技术来管理类之间的关系。
6.代码的模块化和复用:**尽量将功能相似的代码封装成独立的模块或者函数,提高代码的复用性和可维护性。可以使用面向对象的设计原则来组织代码结构,确保代码的清晰易懂。
7.测试和调试:**在设计完成后,一定要进行充分的测试和调试,确保程序能够正常运行并且能够正确处理各种异常情况。可以使用单元测试、集成测试等方法来验证程序的正确性。
总的来说,在处理复杂逻辑和错误报告时,要保持代码的清晰简洁,合理划分模块和功能,注重异常情况的处理,确保程序的稳定性和可靠性。同时,要不断学习和积累经验,及时总结和解决遇到的问题,提高自己的编程能力。
改进建议:
题目难度跨度较大,分数分配不均
总结:
这三次pta真的让我有点苦不堪言,但求学路上总是又很多苦难,只能一个一个的去克服,加油呗。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~