23201927-杨民星-第一次博客
第一次opp题集:
题目数量:5题
题目难度:中等偏难
知识点:ArrayList变长数组,排序,正则表达式,单一职责原则等
对于这次opp题集,我遇到了很多不同的情况,如下细说:
第一、前几题其实都是比较简单的题目,就是让我们认识什么是面向对象程序设计,都是基础,掌握了简单的类于类之间的关系就基本可以解决,但是在这里面有这样一个题目困扰了我很久,题目如下。
7-4 成绩计算-2-关联类 创建成绩类,包含: 属性:平时成绩(int)、期末成绩(int) 方法:计算总成绩(计算规则:平时成绩*0.4+期末成绩*0.6,保留整数部分,小数部分直接丢弃) 创建学生类,包含: 属性:学号(String)、姓名(String)、语文成绩(成绩类)、数学成绩(成绩类)、物理成绩(成绩类) 方法:计算总分、计算平均分 输入3个学生的信息,将每个学生的信息封装在一个学生对象中。 按输入顺序依次输出3个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。 浮点数保留小数的相关知识可参考:https://blog.csdn.net/huaishuming/article/details/17752365 注意:未用学生类对象封装数据的,本题计0分 输入格式: 依次输入3个学生的每门课成绩,每个学生成绩信息格式: 学号+英文空格+姓名+英文空格+课程名+英文空格+平时成绩+英文空格+期末成绩 注:3个学生的课程顺序可能会不一致 例如: 22201311 张琳 语文 70 80 22201311 张琳 数学 85 89 22201311 张琳 物理 75 83 22201312 黄昊 语文 66 78 22201312 黄昊 数学 76 82 22201312 黄昊 物理 83 82 22201313 李少辰 语文 86 76 22201313 李少辰 数学 78 76 22201313 李少辰 物理 87 76 输出格式: 3个学生信息,每个学生信息格式: 学号+英文空格+姓名+英文空格+总成绩+英文空格+平均分 例如: 22201311 张琳 242 80.67 22201312 黄昊 234 78.00 22201313 李少辰 236 78.67 输入样例: 在这里给出一组输入。例如: 22201311 张琳 语文 70 80 22201311 张琳 数学 85 89 22201311 张琳 物理 75 83 22201312 黄昊 语文 66 78 22201312 黄昊 数学 76 82 22201312 黄昊 物理 83 82 22201313 李少辰 语文 86 76 22201313 李少辰 数学 78 76 22201313 李少辰 物理 87 76 输出样例: 在这里给出相应的输出。例如: 22201311 张琳 242 76.67 84.00 80.67 22201312 黄昊 234 75.00 80.67 78.00 22201313 李少辰 236 83.67 76.00 78.67
这个题目本身并不是很难,我最终的解答如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); for (int j = 0; j < 3; j++) { String id = ""; String name = ""; double dailychinese = 0; double finalchinese = 0; double dailymath = 0; double finalmath = 0; double dailyphysics = 0; double finalphysics = 0; for (int i = 0; i < 3; i++) { String[] line = in.nextLine().split(" "); id = line[0]; name = line[1]; if (i == 0) { dailychinese = Double.parseDouble(line[3]); finalchinese = Double.parseDouble(line[4]); } else if (i == 1) { dailymath = Double.parseDouble(line[3]); finalmath = Double.parseDouble(line[4]); } else if (i == 2) { dailyphysics = Double.parseDouble(line[3]); finalphysics = Double.parseDouble(line[4]); } } Student3 student = new Student3(id, name); Test test = new Test(dailychinese, finalchinese, dailymath, finalmath, dailyphysics, finalphysics); student.display(); test.Print(j); } } } class Student3 { private String Id; private String Name; public Student3(String id, String name) { Id = id; Name = name; } public void display() { System.out.printf("%s %s ", Id, Name); } } class Test { private double dailychinese; private double finalchinese; private double dailymath; private double finalmath; private double dailyphysics; private double finalphysics; public Test(double dailychinese, double finalchinese, double dailymath, double finalmath, double dailyphysics, double finalphysics) { this.dailychinese = dailychinese; this.finalchinese = finalchinese; this.dailymath = dailymath; this.finalmath = finalmath; this.dailyphysics = dailyphysics; this.finalphysics = finalphysics; } public double averagedaily() { return (dailychinese + dailymath + dailyphysics) / 3.00; } public double averagefinal() { return (finalchinese + finalmath + finalphysics) / 3.00; } public int chinesesum() { return (int) (dailychinese * 0.40 + finalchinese * 0.60); } public int mathsum() { return (int) (dailymath * 0.40 + finalmath * 0.60); } public int physicssum() { return (int) (dailyphysics * 0.40 + finalphysics * 0.60); } public int sum() { return (int) (chinesesum() + mathsum() + physicssum()); } public double averagesum() { return (double) (sum() / 3.00); } public void Print(int j) { if(j !=2 ) { System.out.printf("%d %.2f %.2f %.2f\n", sum(), averagedaily(), averagefinal(), averagesum()); } else { System.out.printf("%d %.2f %.2f %.2f", sum(), averagedaily(), averagefinal(), averagesum()); } } }
但是在这个问题中有一个一开始困惑我的问题就是在给出的输入样例中,他是多行输入,这个就是说明我之前用的方法就是最大的问题,其实对与这个问题来说,这个是对 于用户输入的最基本的数据输入,因为 多行输入就是在日常生活中的最基本的一件事情,因为我们是无法预知到未来的事,所以这个问题是对于我来说是最为致命的,我就是当 时没想到,然后就没写完,以至于我是在写完最后一题才写完这个的。但是说这个题目的输入和最后一题的输入是有差异的,在这个题目中有很多的重复信息,这些是无效的。 接下来将讲一下我的方法:
这个其实在这里不是普适性的方法,就只是对于这个题目,首先,我把每三个看成一组数据,然后再用for循环来遍历每一个数据,然后就是对于这些数据的位置直接判断,这个就直接将普适性给抹除掉了,但是说对于问题就直接解决了。详情请看main函数里面的代码。
第二、就是对于最后一题的分析于作答:
话不多说,直接上题!
7-5 答题判题程序-1 设计实现答题程序,模拟一个小型的测试,要求输入题目信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。 输入格式: 程序输入信息分三部分: 1、题目数量 格式:整数数值,若超过1位最高位不能为0, 样例:34 2、题目内容 一行为一道题,可以输入多行数据。 格式:"#N:"+题号+" "+"#Q:"+题目内容+" "#A:"+标准答案 格式约束:题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。 样例:#N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 3、答题信息 答题信息按行输入,每一行为一组答案,每组答案包含第2部分所有题目的解题答案,答案的顺序号与题目题号相对应。 格式:"#A:"+答案内容 格式约束:答案数量与第2部分题目的数量相同,答案之间以英文空格分隔。 样例:#A:2 #A:78 2是题号为1的题目的答案 78是题号为2的题目的答案 答题信息以一行"end"标记结束,"end"之后的信息忽略。 输出格式: 1、题目数量 格式:整数数值,若超过1位最高位不能为0, 样例:34 2、答题信息 一行为一道题的答题信息,根据题目的数量输出多行数据。 格式:题目内容+" ~"+答案 样例:1+1=~2 2+2= ~4 3、判题信息 判题信息为一行数据,一条答题记录每个答案的判断结果,答案的先后顺序与题目题号相对应。 格式:判题结果+" "+判题结果 格式约束: 1、判题结果输出只能是true或者false, 2、判题信息的顺序与输入答题信息中的顺序相同 样例:true false true 输入样例1: 单个题目。例如: 1 #N:1 #Q:1+1= #A:2 #A:2 end 输出样例1: 在这里给出相应的输出。例如: 1+1=~2 true 输入样例2: 单个题目。例如: 1 #N:1 #Q:1+1= #A:2 #A:4 end 输出样例2: 在这里给出相应的输出。例如: 1+1=~4 false 输入样例3: 多个题目。例如: 2 #N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 #A:2 #A:4 end 输出样例3: 在这里给出相应的输出。例如: 1+1=~2 2+2=~4 true true 输入样例4: 多个题目。例如: 2 #N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 #A:2 #A:2 end 输出样例4: 在这里给出相应的输出。例如: 1+1=~2 2+2=~2 true false 输入样例5: 多个题目,题号顺序与输入顺序不同。例如: 2 #N:2 #Q:1+1= #A:2 #N:1 #Q:5+5= #A:10 #A:10 #A:2 end 输出样例5: 在这里给出相应的输出。例如: 5+5=~10 1+1=~2 true true 输入样例6: 含多余的空格符。例如: 1 #N:1 #Q: The starting point of the Long March is #A:ruijin #A:ruijin end 输出样例6: 在这里给出相应的输出。例如: The starting point of the Long March is~ruijin true 输入样例7: 含多余的空格符。例如: 1 #N: 1 #Q: 5 +5= #A:10 #A:10 end 输出样例7: 在这里给出相应的输出。例如: 5 +5=~10 true 设计建议: 以下是针对以上题目要求的设计建议,其中的属性、方法为最小集,实现代码中可根据情况添加所需的内容: 题目类(用于封装单个题目的信息): 属性:题目编号、题目内容、标准答案-standardAnswer 方法:数据读写set\get方法、 判题方法(答案-answer):判断答案-answer是否符合标准答案-standardAnswer 试卷类(用于封装整套题目的信息) 属性:题目列表(题目类的对象集合)、题目数量 方法:判题方法(题号-num、答案-answer):判断答案-answer是否符合对应题号的题目标准答案-standardAnswer 保存题目(题号-num、题目-question):将题目保存到题目列表中,保存位置与num要能对应 答卷类(用于封装答题信息) 属性:试卷(试卷类的对象)、答案列表(保存每一题的答案)、判题列表(保存每一题的判题结果true/false) 方法:判题方法(题号-num):判断答案列表中第num题的结果是否符合试卷中对应题号的题目标准答案 输出方法(题号-num):按照题目的格式要求,输出题号为num的题目的内容和答题结果。 保存一个答案(题号-num,答案-answer):保存题号为num的题目的答题结果answer。
一看直接好家伙,题目就直接是这么长了。但是没关系,越长的题目给出的可用信息越多,这是个好消息啊。
题目是一看就难,但是本质很简单的那种,就是将输入的对应的信息给识别,遍历,比较,输出。写完了3次opp题集就会发现其实基本上就是这个问题,只不过是往里面加了好多的东西。
模拟场景:单张试卷的信息处理
详细内容:输入试卷中试题的信息(编号、题目、标准答案)
输出试题每一题的答题信息以及最后每一题的判题结果
接下来就是我的代码:
import java.util.ArrayList; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); in.nextLine(); String[] Line = new String[n]; // String[] S; ArrayList<Question> qu = new ArrayList<Question>(); Exam exam = new Exam(qu, n); for(int i = 0; i < n; i++) { Line[i] = in.nextLine(); String[] S = Line[i].split("\\s*#N:\\s*|\\s*#Q:\\s*|\\s*#A:\\s*"); int num = Integer.parseInt(S[1]); qu.add(new Question(num , S[2] , S[3])); } exam.sort(); ArrayList<String> selfanswer = new ArrayList<String>(); for(int i = 0;i < n;i++){ String str = in.next(); String[] sa = str.split("\\s*#A:\\s*"); selfanswer.add(sa[1]); } Answer answer = new Answer(selfanswer, new ArrayList<Boolean>(), new Exam(qu, n)); for(int i = 0 ; i < n ; i ++) { answer.PrintIn(i); } for(int i = 0 ; i < n ; i ++ ) { if(i != n-1) { System.out.printf("%b ",answer.judgement(i, selfanswer)); } else { System.out.printf("%b",answer.judgement(i, selfanswer)); } } String end = in.next(); if(end.equals("end")){ System.exit(0); } } } class Question { private int num; private String input; private String standardAnswer; public Question(int num, String input, String standardAnswer) { this.num = num; this.input = input; this.standardAnswer = standardAnswer; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getInput() { return input; } public void setInput(String input) { this.input = input; } public String getStandardAnswer() { return standardAnswer; } public void setStandardAnswer(String standardAnswer) { this.standardAnswer = standardAnswer; } } class Exam { private ArrayList<Question> questions = new ArrayList<Question>(); private int number; public Exam(ArrayList<Question> questions, int number) { this.questions = questions; this.number = number; } public ArrayList<Question> getQuestions() { return questions; } public void setQuestions(ArrayList<Question> questions) { this.questions = questions; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public void sort() { int n = questions.size(); for(int i = 0; i < n - 1; i++) { for(int j = 0; j < n - i - 1; j++) { if(questions.get(j).getNum() > (questions.get(j + 1).getNum())) { Question temp = questions.get(j); questions.set(j, questions.get(j + 1)); questions.set(j + 1, temp); } } } } } class Answer { private ArrayList<String> Answer; private ArrayList<Boolean> judger; private Exam exam; public Answer(ArrayList<String> answer, ArrayList<Boolean> judger, Exam exam) { Answer = answer; this.judger = judger; this.exam = exam; } public ArrayList<String> getAnswer() { return Answer; } public void setAnswer(ArrayList<String> answer) { Answer = answer; } public ArrayList<Boolean> getJudger() { return judger; } public void setJudger(ArrayList<Boolean> judger) { this.judger = judger; } public Exam getExam() { return exam; } public void setExam(Exam exam) { this.exam = exam; } public boolean judgement(int N , ArrayList<String> selfanswer) { return selfanswer.get(N).equals(exam.getQuestions().get(N).getStandardAnswer()); } public void PrintIn(int N) { System.out.println(exam.getQuestions().get(N).getInput() + "~" + Answer.get(N)); } }
这个就是我作答的代码,接下来就是我的类图:
这个是SourceMontor中代码的数据:
创建了3个类,按照老师给的提示去写的。题目类,试卷类和答卷类。但是,其实再主函数中就直接出现了问题,就是在这个里面,我把匹配分割的这部分就直接放在了主函数中,这是一个很严重的问题,这个违背了面型对象程序设计中六大基本原则中的单一职责原则。
先分析一下我的这些类吧。
1、首先就是题目类,这个的主要职责就是对于题目信息的封装,题目数目,题目本身和题目的标准答案。
2、试卷类,这个类就是储存试卷的信息,对试卷进行封装。里面包括了题目类的题目和题目的总数目。在方法中进行了对于题目的排序,符合题目的要求。
3、答卷类,这个类就是对于题目的答案和考生作答的进行比较。将比较好的结果在方法中直接返回或者是输出。
这里还应该再加上一个类会更加完善,就是判断类,这个类的主要功能就是对于输入的数据用正则表达式来进行判断和进行切割,然后再将判断值通过布尔的类型值返回进行发判断,有以及将分割完就直接储存再数组中去,这样的话会更加完美,解决的单一 职责的问题。
接下类看一下老师在之后给出的正则表达式:
第一次题集总结:
1、对于输入的进一步了解,明确程序中的输入和现实生活中的重要意义。
2、了解到类与类之间的关系及其规范性,更加直观的体会到了单一职责的应用,体会到了这个原则对于面向对象的意义,就是对于本次题集的最后一题中的判断类。
3、粗略学习了ArrayList变长数组的用法以及功能,为后续的学习做准备。
第二次opp题集:
题目数量:四题
题目难度:难
考察知识点:单一职责原则,正则表达式,链表以及数组等
对于第二次的题集,先不说题集,先进行自我批判,就是以后不要在没写完opp之前不要想着出去耍,这样会让你写不下去,出去玩不如在工场写题目集和学习。
对于这个题集,最后一题就有明显的难度了,主要就是最后一题的分析。接下来就是对最后一题进行分析:
这题将题目全放进来,先来一个总体分析,后面再一个一个题目模块进行分析。
7-4 答题判题程序-2 设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-1基础上增补或者修改的内容。 要求输入题目信息、试卷信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。 输入格式: 程序输入信息分三种,三种信息可能会打乱顺序混合输入: 1、题目信息 一行为一道题,可输入多行数据(多道题)。 格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案 格式约束: 1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。 2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。 样例:#N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 2、试卷信息 一行为一张试卷,可输入多行数据(多张卷)。 格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值 题目编号应与题目信息中的编号对应。 一行信息中可有多项题目编号与分值。 样例:#T:1 3-5 4-8 5-2 3、答卷信息 答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序与试卷信息中的题目顺序相对应。 格式:"#S:"+试卷号+" "+"#A:"+答案内容 格式约束:答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。 样例:#S:1 #A:5 #A:22 1是试卷号 5是1号试卷的顺序第1题的题目答案 22是1号试卷的顺序第2题的题目答案 答题信息以一行"end"标记结束,"end"之后的信息忽略。 输出格式: 1、试卷总分警示 该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100分,该部分忽略,不输出。 格式:"alert: full score of test paper"+试卷号+" is not 100 points" 样例:alert: full score of test paper2 is not 100 points 2、答卷信息 一行为一道题的答题信息,根据试卷的题目的数量输出多行数据。 格式:题目内容+"~"+答案++"~"+判题结果(true/false) 约束:如果输入的答案信息少于试卷的题目数量,答案的题目要输"answer is null" 样例:3+2=~5~true 4+6=~22~false. answer is null 3、判分信息 判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。 格式:题目得分+" "+....+题目得分+"~"+总分 格式约束: 1、没有输入答案的题目计0分 2、判题信息的顺序与输入答题信息中的顺序相同 样例:5 8 0~13 根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。 4、提示错误的试卷号 如果答案信息中试卷的编号找不到,则输出”the test paper number does not exist”,参见样例9。 设计建议: 参考答题判题程序-1,建议增加答题类,类的内容以及类之间的关联自行设计。 输入样例1: 一张试卷一张答卷。试卷满分不等于100。例如: #N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 #T:1 1-5 2-8 #S:1 #A:5 #A:22 end 输出样例1: 在这里给出相应的输出。例如: alert: full score of test paper1 is not 100 points 1+1=~5~false 2+2=~22~false 0 0~0 输入样例2: 一张试卷一张答卷。试卷满分不等于100。例如: #N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 #T:1 1-70 2-30 #S:1 #A:5 #A:22 end 输出样例2: 在这里给出相应的输出。例如: 1+1=~5~false 2+2=~22~false 0 0~0 输入样例3: 一张试卷、一张答卷。各类信息混合输入。例如: #N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 #T:1 1-70 2-30 #N:3 #Q:3+2= #A:5 #S:1 #A:5 #A:4 end 输出样例: 在这里给出相应的输出。例如: 1+1=~5~false 2+2=~4~true 0 30~30 输入样例4: 试卷题目的顺序与题号不一致。例如: #N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 #T:1 2-70 1-30 #N:3 #Q:3+2= #A:5 #S:1 #A:5 #A:22 end 输出样例: 在这里给出相应的输出。例如: 2+2=~5~false 1+1=~22~false 0 0~0 输入样例5: 乱序输入。例如: #N:3 #Q:3+2= #A:5 #N:2 #Q:2+2= #A:4 #T:1 3-70 2-30 #S:1 #A:5 #A:22 #N:1 #Q:1+1= #A:2 end 输出样例: 在这里给出相应的输出。例如: 3+2=~5~true 2+2=~22~false 70 0~70 输入样例6: 乱序输入+两份答卷。例如: #N:3 #Q:3+2= #A:5 #N:2 #Q:2+2= #A:4 #T:1 3-70 2-30 #S:1 #A:5 #A:22 #N:1 #Q:1+1= #A:2 #S:1 #A:5 #A:4 end 输出样例: 在这里给出相应的输出。例如: 3+2=~5~true 2+2=~22~false 70 0~70 3+2=~5~true 2+2=~4~true 70 30~100 输入样例7: 乱序输入+分值不足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 #S:1 #A:5 #A:4 end 输出样例: 在这里给出相应的输出。例如: alert: full score of test paper1 is not 100 points 3+2=~5~true 2+2=~22~false 7 0~7 3+2=~5~true 2+2=~4~true 7 6~13 输入样例8: 乱序输入+分值不足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 alert: full score of test paper2 is not 100 points 3+2=~5~true 2+2=~22~false 7 0~7 2+2=~5~false 1+1=~4~false answer is null 0 0 0~0 输入样例9: 乱序输入+分值不足100+两份答卷+无效的试卷号。例如: #N:3 #Q:3+2= #A:5 #N:2 #Q:2+2= #A:4 #T:1 3-7 2-6 #S:3 #A:5 #A:4 end 输出样例: 在这里给出相应的输出。例如: alert: full score of test paper1 is not 100 points The test paper number does not exist
首先就是对于题目的分析:
1、模拟场景:多张试卷、多张答卷的信息处理
2、详细内容: a、输入试题的信息(编号、题目、标准答案)、试卷引用信息(试卷号、引用的题目号-分值)、答卷信息(试卷号、答案)
b、输出试题每一题的答题、判题信息以及最后每一题的判分结果、总分。
这个就是对于整个题目进行的分析,这要的部分就是这样,接下来详细分析一下题目的每个板块:
1、题目信息 一行为一道题,可输入多行数据(多道题)。 格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案 格式约束: 1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。 2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。 样例:#N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4
首先就是第一部分,这个部分告诉我们的就是题目的信息,在这里要重点注意的是格式,和第一次的是一样的,再者,注意约束条件,这个会对后续输入的判断有很重要的联系,重点注意!
2、试卷信息 一行为一张试卷,可输入多行数据(多张卷)。 格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值 题目编号应与题目信息中的编号对应。 一行信息中可有多项题目编号与分值。 样例:#T:1 3-5 4-8 5-2
这个是第二部分,也是这次相比较上次新添加的东西之一,但是这个也是和之前的八九不离十,也是格式问题,其实我个人是喜欢看样例的,这样更直观,但是这个习惯很不好的,这样的话不能深刻理解到这个信息的真正意思,这个就是着3次题目集我踩坑之一,这个坑很致命的!
3、答卷信息 答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序与试卷信息中的题目顺序相对应。 格式:"#S:"+试卷号+" "+"#A:"+答案内容 格式约束:答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。 样例:#S:1 #A:5 #A:22 1是试卷号 5是1号试卷的顺序第1题的题目答案 22是1号试卷的顺序第2题的题目答案 答题信息以一行"end"标记结束,"end"之后的信息忽略。
第三部分就是答卷信息,这个在之前的基础上加上了一个“#S”来判断答题的人。
1、试卷总分警示 该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100分,该部分忽略,不输出。 格式:"alert: full score of test paper"+试卷号+" is not 100 points" 样例:alert: full score of test paper2 is not 100 points 2、答卷信息 一行为一道题的答题信息,根据试卷的题目的数量输出多行数据。 格式:题目内容+"~"+答案++"~"+判题结果(true/false) 约束:如果输入的答案信息少于试卷的题目数量,答案的题目要输"answer is null" 样例:3+2=~5~true 4+6=~22~false. answer is null 3、判分信息 判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。 格式:题目得分+" "+....+题目得分+"~"+总分 格式约束: 1、没有输入答案的题目计0分 2、判题信息的顺序与输入答题信息中的顺序相同 样例:5 8 0~13 根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。 4、提示错误的试卷号 如果答案信息中试卷的编号找不到,则输出”the test paper number does not exist”,参见样例9。
最后一部分就是最后的输出问题,一共就是四点:
1、要算总分,判断,输出。
2、判断的题目和答案的正确与否
3、要根据答题得分情况来确定最后得的总分。
4、要判断答题的编号,然后输出。
这一些点都很重要,都是从题集1中迭代过来的扩展信息,到了第3次题集你就会发现,第三次的条件好像的,哈哈哈 ,这就是段老师口中迭代的魅力!!!
接下来就是我写的代码,这次的代码就是垃圾,就是垃圾的,后面写过一个,大体的逻辑是没有问题的,但是,由于博主是智障!本来想把之前写过的代码传到gitee中的时候,手贱把之前写过的所有代码都删除了,过程不说,伤心,知道博主是智障就好,sad,但是还好之前的类图没删除。
1 import java.util.*; 2 3 class Question { 4 String number; 5 String content; 6 String answer; 7 8 public Question(String number, String content, String answer) { 9 this.number = number; 10 this.content = content; 11 this.answer = answer; 12 } 13 } 14 15 class TestPaper { 16 String number; 17 Map<String, Integer> questions; 18 19 public TestPaper(String number) { 20 this.number = number; 21 this.questions = new HashMap<>(); 22 } 23 24 public void addQuestion(String questionNumber, int score) { 25 questions.put(questionNumber, score); 26 } 27 } 28 29 class AnswerSheet { 30 String testPaperNumber; 31 List<String> answers; 32 33 public AnswerSheet(String testPaperNumber) { 34 this.testPaperNumber = testPaperNumber; 35 this.answers = new ArrayList<>(); 36 } 37 38 public void addAnswer(String answer) { 39 answers.add(answer); 40 } 41 } 42 43 public class Main { 44 public static void main(String[] args) { 45 Scanner scanner = new Scanner(System.in); 46 List<Question> questions = new ArrayList<>(); 47 Map<String, TestPaper> testPapers = new HashMap<>(); 48 List<AnswerSheet> answerSheets = new ArrayList<>(); 49 50 String line; 51 while (!(line = scanner.nextLine()).equals("end")) { 52 if (line.startsWith("#N:")) { 53 String[] parts = line.split(" "); 54 String number = parts[0].substring(4); 55 String content = parts[1].substring(3); 56 String answer = parts[2].substring(3); 57 questions.add(new Question(number, content, answer)); 58 } else if (line.startsWith("#T:")) { 59 String[] parts = line.split(" "); 60 String testPaperNumber = parts[0].substring(3); 61 TestPaper testPaper = new TestPaper(testPaperNumber); 62 for (int i = 1; i < parts.length; i++) { 63 String[] questionInfo = parts[i].split("-"); 64 testPaper.addQuestion(questionInfo[0], Integer.parseInt(questionInfo[1])); 65 } 66 testPapers.put(testPaperNumber, testPaper); 67 } else if (line.startsWith("#S:")) { 68 String[] parts = line.split(" "); 69 String testPaperNumber = parts[0].substring(3); 70 AnswerSheet answerSheet = new AnswerSheet(testPaperNumber); 71 for (int i = 1; i < parts.length; i++) { 72 answerSheet.addAnswer(parts[i].substring(3)); 73 } 74 answerSheets.add(answerSheet); 75 } 76 } 77 78 for (AnswerSheet answerSheet : answerSheets) { 79 int totalScore = 0; 80 int questionCount = 0; 81 boolean hasNullAnswer = false; 82 TestPaper testPaper = testPapers.get(answerSheet.testPaperNumber); 83 for (Map.Entry<String, Integer> entry : testPaper.questions.entrySet()) { 84 String questionNumber = entry.getKey(); 85 int score = entry.getValue(); 86 boolean answered = false; 87 for (Question question : questions) { 88 if (question.number.equals(questionNumber)) { 89 questionCount++; 90 if (answerSheet.answers.size() >= questionCount) { 91 String userAnswer = answerSheet.answers.get(questionCount - 1); 92 boolean result = userAnswer.equals(question.answer); 93 totalScore += result ? score : 0; 94 System.out.println(question.content + "~" + userAnswer + "~" + result); 95 answered = true; 96 } 97 break; 98 } 99 } 100 if (!answered) { 101 System.out.println("answer is null"); 102 hasNullAnswer = true; 103 } 104 } 105 if (totalScore != 100) { 106 System.out.println("alert: full score of test paper" + answerSheet.testPaperNumber + " is not 100 points"); 107 } 108 System.out.println("0 ".repeat(Math.max(0, questionCount)) + "~" + totalScore); 109 } 110 } 111 }
类图如下:
下面是SourceMontor中的数据:
以上就是opp第二次的题目的思路和做法,接下来总结一下:
1、首先就是对题目的分析,这个是先比第一次的明显差别,这就说明读懂题目的重要性,之后的题目一定是更复杂的。
2、然后就是对于数据的输入的读取的问题,这个是非常大的区别,这个要存在一个变长数组中,然后再用变长数组中的方法进行分类,这个是输入的关键点。在第三题中也是这个的方法哦。
3、还是对于链表和ArrayList的运用,他们里面的方法的应用非常重要,在第三次中也用了很多。
第三次opp题集
题目数目:3题
题目难度:比第二题难(虽然是废话)
知识点:java中的date类的应用,单一职责原则,ArrayList以及链表的运用等等
第二题的题目介绍方法和第二题一样,还要再加一个第2题,那题很有意思。首先我们来看看第二题:
7-2 jmu-java-日期类的基本使用 给定一个日期,判定是否为合法日期。如果合法,判断该年是否闰年,该日期是当年第几天、当月第几天、当周第几天、。 给定起始日期与结束日期,判定日期是否合法且结束日期是否早于起始日期。如果均合法,输出结束日期与起始日期之间的相差的天数、月数、念书。 输入格式: 第一行输入一个日期字符串,格式为"YYYY-MM-dd" 第二行输入两个日期字符串,中间使用空格隔开。分别代表开始日期与结束日期。 输出格式: 如果第一行日期字符串非法,输出自定义的错误信息。 如果第一行日期有效,输出相关信息,如果是闰年要输出是闰年。 如果第二行两个日期,只要有一个无效。就输出相关错误信息。 如果第二行两个日期有效且结束日期不早于开始日期,输出相关信息。 输入样例1: 第一行日期非法、第二行有日期非法 2020-02-30 2020-02-30 2020-01-02 输出样例1: 2020-02-30无效! 2020-02-30或2020-01-02中有不合法的日期. 输入样例2: 均有效且合法 2021-02-28 2019-08-01 2020-01-02 输出样例2: 2021-02-28是当年第59天,当月第28天,当周第7天. 2020-01-02与2019-08-01之间相差154天,所在月份相差-7,所在年份相差1. 输入样例3: 日期均有效,但结束日期早于开始日期 2020-02-28 2020-02-02 2020-02-01 输出样例3: 2020-02-28是闰年. 2020-02-28是当年第59天,当月第28天,当周第5天. 2020-02-01早于2020-02-02,不合法!
这题乍一看其实挺简单的,如果你知道date类的方法的话就会很快的,date类的方法参考java程序设计这本书,还可以自己再网络上搜索学习。接下来是答题代码:
1 import java.time.DayOfWeek; 2 import java.time.LocalDate; 3 import java.time.temporal.ChronoUnit; 4 import java.util.Scanner; 5 6 public class Main { 7 8 public static void main(String[] args) { 9 // TODO 自动生成的方法存根 10 11 Scanner in = new Scanner(System.in); 12 String[] year = new String[3]; 13 String[] month = new String[3]; 14 String[] day = new String[3]; 15 16 String date1 = in.nextLine(); 17 String[] S = date1.split("-"); 18 year[0] = (S[0]); 19 month[0] = (S[1]); 20 day[0] = (S[2]); 21 22 String date2 = in.nextLine(); 23 String[] s = date2.split(" "); 24 for(int i = 0 ; i < 2 ; i ++) { 25 String[] s1 = s[i].split("-"); 26 year[i + 1] = (s1[0]); 27 month[i + 1] = (s1[1]); 28 day[i + 1] = (s1[2]); 29 } 30 31 Year year1 = new Year(year[0]); 32 Month month1 = new Month(month[0]); 33 Day day1 = new Day(day[0]); 34 Year year2 = new Year(year[1]); 35 Month month2 = new Month(month[1]); 36 Day day2 = new Day(day[1]); 37 Year year3 = new Year(year[2]); 38 Month month3 = new Month(month[2]); 39 Day day3 = new Day(day[2]); 40 Judgement judgement1 = new Judgement(year1 , month1 , day1); 41 Judgement judgement2 = new Judgement(year2 , month2 , day2 , year3 , month3 , day3); 42 Judgement judgement3 = new Judgement(year2 , month2 , day2); 43 Judgement judgement4 = new Judgement(year3 , month3 , day3); 44 45 if(judgement1.judgementone() == 1) { 46 if(judgement1.getYear().isLeapyear()) { 47 System.out.println(date1 + "是闰年."); 48 judgement1.oneDay(); 49 } else { 50 judgement1.oneDay(); 51 } 52 } else { 53 System.out.println(date1 + "无效!"); 54 } 55 56 // if(!judgement1.judgementone()) { 57 // System.out.println(date1 + "无效!"); 58 // } else { 59 // if(judgement1.getYear().isLeapyear()) { 60 // System.out.println(date1 + "是闰年."); 61 // judgement1.oneDay(); 62 // } else { 63 // judgement1.oneDay(); 64 // } 65 // } 66 67 if(judgement3.judgementone() == 0 || judgement4.judgementone() == 0) { 68 System.out.print(s[0] + "或" + s[1] + "中有不合法的日期."); 69 } else if(!judgement2.judgementtwo()){ 70 System.out.print(s[1] + "早于" + s[0] + ",不合法!"); 71 } else { 72 judgement2.twoDay(); 73 } 74 } 75 76 } 77 78 class Year { 79 private String year; 80 81 public Year() { 82 super(); 83 // TODO 自动生成的构造函数存根 84 } 85 86 public Year(String year) { 87 super(); 88 this.year = year; 89 } 90 91 public String getYear() { 92 return year; 93 } 94 95 public void setYear(String year) { 96 this.year = year; 97 } 98 99 public boolean isLeapyear() { 100 return (Integer.parseInt(year) % 4 == 0 && Integer.parseInt(year) % 100 != 0) || Integer.parseInt(year) % 400 == 0 ; 101 } 102 103 } 104 105 class Month { 106 private String month; 107 108 public Month() { 109 super(); 110 // TODO 自动生成的构造函数存根 111 } 112 113 public Month(String month) { 114 super(); 115 this.month = month; 116 } 117 118 public String getMonth() { 119 return month; 120 } 121 122 public void setMonth(String month) { 123 this.month = month; 124 } 125 126 } 127 128 class Day { 129 private String day; 130 131 public Day() { 132 super(); 133 // TODO 自动生成的构造函数存根 134 } 135 136 public Day(String day) { 137 super(); 138 this.day = day; 139 } 140 141 public String getDay() { 142 return day; 143 } 144 145 public void setDay(String day) { 146 this.day = day; 147 } 148 149 } 150 151 class Judgement { 152 private Year year; 153 private Month month; 154 private Day day; 155 private Year year1; 156 private Month month1; 157 private Day day1; 158 159 public Judgement() { 160 super(); 161 // TODO 自动生成的构造函数存根 162 } 163 164 165 public Judgement(Year year, Month month, Day day) { 166 super(); 167 this.year = year; 168 this.month = month; 169 this.day = day; 170 } 171 172 173 public Judgement(Year year, Month month, Day day, Year year1, Month month1, Day day1) { 174 super(); 175 this.year = year; 176 this.month = month; 177 this.day = day; 178 this.year1 = year1; 179 this.month1 = month1; 180 this.day1 = day1; 181 } 182 183 public Year getYear() { 184 return year; 185 } 186 187 public void setYear(Year year) { 188 this.year = year; 189 } 190 191 public Month getMonth() { 192 return month; 193 } 194 195 public void setMonth(Month month) { 196 this.month = month; 197 } 198 199 public Day getDay() { 200 return day; 201 } 202 203 public void setDay(Day day) { 204 this.day = day; 205 } 206 207 public Year getYear1() { 208 return year1; 209 } 210 211 public void setYear1(Year year1) { 212 this.year1 = year1; 213 } 214 215 public Month getMonth1() { 216 return month1; 217 } 218 219 public void setMonth1(Month month1) { 220 this.month1 = month1; 221 } 222 223 public Day getDay1() { 224 return day1; 225 } 226 227 public void setDay1(Day day1) { 228 this.day1 = day1; 229 } 230 231 public int judgementone() { 232 // String[] month1 = {"01" , "02" , "03" , "04" , "05" , "06" , "07" , "08" , "09" , "10" , "11" , "12" }; 233 // String[] day1 = {"01" , "02" , "03" , "04" , "05" , "06" , "07" , "08" , "09"}; 234 String[] month_day = {"0" , "31" , "28" , "31" , "30" , "31" , "30" , "31" , "31" , "30" , "31" , "30" , "31"}; 235 // 236 // int a = 0; 237 // if(Integer.parseInt(day.getDay()) >0 && Integer.parseInt(day.getDay()) <10) { 238 // if(day.getDay().equals(day1[Integer.parseInt(day.getDay()) - 1])) { 239 // a = 1; 240 // }else { 241 // a = 0; 242 // } 243 // } 244 // 245 // if(year.isLeapyear()) { 246 // month_day[2] = "29"; 247 // } else { 248 // month_day[2] = "28"; 249 // } 250 // 251 // int b = 0 ; 252 // if(year.getYear().length() == 4 && year.getYear().matches("[0-9]+")) { 253 // b = 1; 254 // } else { 255 // b = 0; 256 // } 257 // if(month.getMonth().equals(month1[Integer.parseInt(month.getMonth()) - 1]) && ((Integer.parseInt(day.getDay()) > 9 && Integer.parseInt(day.getDay()) <= Integer.parseInt(month_day[Integer.parseInt(month.getMonth())])) || a == 1) && b == 1) { 258 // return 1; 259 // } else { 260 // return 0; 261 // } 262 int a = 0; 263 int b = 0; 264 int c = 0; 265 if(year.getYear().length() == 4 && year.getYear().matches("[\\d]{4}")) { 266 a = 1; 267 } 268 if(month.getMonth().length() == 2 && month.getMonth().matches("[\\d]{2}") && Integer.parseInt(month.getMonth()) < 13) { 269 b = 1; 270 } 271 if(day.getDay().length() == 2 && day.getDay().matches("[\\d]{2}")) { 272 c = 1; 273 } 274 if(a == 1 && b == 1 && c == 1 && Integer.parseInt(day.getDay()) > 0 && Integer.parseInt(day.getDay()) <= Integer.parseInt(month_day[Integer.parseInt(month.getMonth())])) { 275 return 1; 276 } else { 277 return 0; 278 } 279 } 280 281 public void oneDay() { 282 LocalDate startDate = LocalDate.of(Integer.parseInt(year.getYear()), 1, 1); 283 LocalDate endDate = LocalDate.of(Integer.parseInt(year.getYear()), Integer.parseInt(month.getMonth()), Integer.parseInt(day.getDay())); 284 long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);//计算距离这一年的天数 285 286 // LocalDate date = LocalDate.of(Integer.parseInt(year.getYear()), Integer.parseInt(month.getMonth()), Integer.parseInt(day.getDay())); 287 // DayOfWeek dayOfWeek = date.getDayOfWeek(); 288 // int dayOfWeekValue = dayOfWeek.getValue();//计算第几天 289 // System.out.println("2021年2月28日是这周的第 " + dayOfWeekValue + " 天"); 290 291 LocalDate startDate1 = LocalDate.of(1900,1,1); 292 long daysBetween1 = ChronoUnit.DAYS.between(startDate1, endDate); 293 int dayOfWeekValue = ((int) (daysBetween1 + 1)) % 7; 294 System.out.printf("%s-%s-%s是当年第%d天,当月第%d天,当周第%d天.\n" , year.getYear() , month.getMonth() , day.getDay() , daysBetween + 1 , Integer.parseInt(day.getDay()) , dayOfWeekValue); 295 296 } 297 298 public boolean judgementtwo() { 299 LocalDate date1 = LocalDate.of(Integer.parseInt(year.getYear()), Integer.parseInt(month.getMonth()), Integer.parseInt(day.getDay())); 300 LocalDate date2 = LocalDate.of(Integer.parseInt(year1.getYear()), Integer.parseInt(month1.getMonth()), Integer.parseInt(day1.getDay())); 301 int comparison = date1.compareTo(date2); 302 if(comparison <= 0) { 303 return true; 304 }else { 305 return false; 306 } 307 308 } 309 310 public void twoDay() { 311 LocalDate startDate = LocalDate.of(Integer.parseInt(year.getYear()), Integer.parseInt(month.getMonth()), Integer.parseInt(day.getDay())); 312 LocalDate endDate = LocalDate.of(Integer.parseInt(year1.getYear()), Integer.parseInt(month1.getMonth()), Integer.parseInt(day1.getDay())); 313 long daysBetween = ChronoUnit.DAYS.between(startDate, endDate); 314 315 int monthBetween = Integer.parseInt(month1.getMonth()) - Integer.parseInt(month.getMonth()); 316 int yearBetween = Integer.parseInt(year1.getYear()) - Integer.parseInt(year.getYear()); 317 System.out.printf("%s-%s-%s与%s-%s-%s之间相差%d天,所在月份相差%d,所在年份相差%d.", year1.getYear() , month1.getMonth() , day1.getDay() , year.getYear() , month.getMonth() , day.getDay() , daysBetween , monthBetween , yearBetween); 318 } 319 }
这个我主要想讲的就是对于第一行日期有问题,第二行的两个日期是没问题的,但是我之前的代码就是如果是这两个日期完全相同的时候,就会输出错误,最后发现是在第302行的判断中要加等号,这样就不会有问题了,我这就是明显的逻辑的问题,踩了逻辑的坑,这是比较致命的。
接下来就是第三题,这个题目一直都是对于题目的理解的问题,所以我在这里还是要强调一下题目的重要性,不能直接通过样例来判断题目,要通过题目来抽象样例,这个也是段老师给我们讲的非常重要的一个能力。接下来就进行题目分析:
7-3 答题判题程序-3 设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-2基础上增补或者修改的内容,要求输入题目信息、试卷信息、答题信息、学生信息、删除题目信息,根据输入题目信息中的标准答案判断答题的结果。 输入格式: 程序输入信息分五种,信息可能会打乱顺序混合输入。 1、题目信息 题目信息为独行输入,一行为一道题,多道题可分多行输入。 格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案 格式约束: 1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。 2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。 样例:#N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 2、试卷信息 试卷信息为独行输入,一行为一张试卷,多张卷可分多行输入数据。 格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值+" "+题目编号+"-"+题目分值+... 格式约束: 题目编号应与题目信息中的编号对应。 一行信息中可有多项题目编号与分值。 样例:#T:1 3-5 4-8 5-2 3、学生信息 学生信息只输入一行,一行中包括所有学生的信息,每个学生的信息包括学号和姓名,格式如下。 格式:"#X:"+学号+" "+姓名+"-"+学号+" "+姓名....+"-"+学号+" "+姓名 格式约束: 答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。 样例: #S:1 #A:5 #A:22 1是试卷号 5是1号试卷的顺序第1题的题目答案 4、答卷信息 答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序号与试 卷信息中的题目顺序相对应。答卷中: 格式:"#S:"+试卷号+" "+学号+" "+"#A:"+试卷题目的顺序号+"-"+答案内容+... 格式约束: 答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。 答案内容可以为空,即””。 答案内容中如果首尾有多余的空格,应去除后再进行判断。 样例: #T:1 1-5 3-2 2-5 6-9 4-10 7-3 #S:1 20201103 #A:2-5 #A:6-4 1是试卷号 20201103是学号 2-5中的2是试卷中顺序号,5是试卷第2题的答案,即T中3-2的答案 6-4中的6是试卷中顺序号,4是试卷第6题的答案,即T中7-3的答案 注意:不要混淆顺序号与题号 5、删除题目信息 删除题目信息为独行输入,每一行为一条删除信息,多条删除信息可分多行输入。该信息用于删除一道题目信息,题目被删除之后,引用该题目的试卷依然有效,但被删除的题目将以0分计,同时在输出答案时,题目内容与答案改为一条失效提示,例如:”the question 2 invalid~0” 格式:"#D:N-"+题目号 格式约束: 题目号与第一项”题目信息”中的题号相对应,不是试卷中的题目顺序号。 本题暂不考虑删除的题号不存在的情况。 样例: #N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 #T:1 1-5 2-8 #X:20201103 Tom-20201104 Jack #S:1 20201103 #A:1-5 #A:2-4 #D:N-2 end 输出 alert: full score of test paper1 is not 100 points 1+1=~5~false the question 2 invalid~0 20201103 Tom: 0 0~0 答题信息以一行"end"标记结束,"end"之后的信息忽略。 输出格式: 1、试卷总分警示 该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100 分,该部分忽略,不输出。 格式:"alert: full score of test paper"+试卷号+" is not 100 points" 样例:alert: full score of test paper2 is not 100 points 2、答卷信息 一行为一道题的答题信息,根据试卷的题目的数量输出多行数据。 格式:题目内容+"~"+答案++"~"+判题结果(true/false) 约束:如果输入的答案信息少于试卷的题目数量,每一个缺失答案的题目都要输出"answer is null" 。 样例: 3+2=~5~true 4+6=~22~false. answer is null 3、判分信息 判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。 格式:**学号+" "+姓名+": "**+题目得分+" "+....+题目得分+"~"+总分 格式约束: 1、没有输入答案的题目、被删除的题目、答案错误的题目计0分 2、判题信息的顺序与输入答题信息中的顺序相同 样例:20201103 Tom: 0 0~0 根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。 4、被删除的题目提示信息 当某题目被试卷引用,同时被删除时,答案中输出提示信息。样例见第5种输入信息“删除题目信息”。 5、题目引用错误提示信息 试卷错误地引用了一道不存在题号的试题,在输出学生答案时,提示”non-existent question~”加答案。例如: 输入: #N:1 #Q:1+1= #A:2 #T:1 3-8 #X:20201103 Tom-20201104 Jack-20201105 Www #S:1 20201103 #A:1-4 end 输出: alert: full score of test paper1 is not 100 points non-existent question~0 20201103 Tom: 0~0 如果答案输出时,一道题目同时出现答案不存在、引用错误题号、题目被删除,只提示一种信息,答案不存在的优先级最高,例如: 输入: #N:1 #Q:1+1= #A:2 #T:1 3-8 #X:20201103 Tom-20201104 Jack-20201105 Www #S:1 20201103 end 输出: alert: full score of test paper1 is not 100 points answer is null 20201103 Tom: 0~0 6、格式错误提示信息 输入信息只要不符合格式要求,均输出”wrong format:”+信息内容。 例如:wrong format:2 #Q:2+2= #4 7、试卷号引用错误提示输出 如果答卷信息中试卷的编号找不到,则输出”the test paper number does not exist”,答卷中的答案不用输出,参见样例8。 8、学号引用错误提示信息 如果答卷中的学号信息不在学生列表中,答案照常输出,判分时提示错误。参见样例9。 本题暂不考虑出现多张答卷的信息的情况。 输入样例1: 简单输入,不含删除题目信息。例如: #N:1 #Q:1+1= #A:2 #T:1 1-5 #X:20201103 Tom #S:1 20201103 #A:1-5 end 输出样例1: 在这里给出相应的输出。例如: alert: full score of test paper1 is not 100 points 1+1=~5~false 20201103 Tom: 0~0 输入样例2: 简单输入,答卷中含多余题目信息(忽略不计)。例如: #N:1 #Q:1+1= #A:2 #T:1 1-5 #X:20201103 Tom #S:1 20201103 #A:1-2 #A:2-3 end 输出样例3 简单测试,含删除题目信息。例如: alert: full score of test paper1 is not 100 points 1+1=~2~true 20201103 Tom: 5~5 输入样例3: 简单测试,含删除题目信息。例如: #N:1 #Q: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 #A:2-4 #D:N-2 end 输出样例3: 在这里给出相应的输出,第二题由于被删除,输出题目失效提示。例如: alert: full score of test paper1 is not 100 points 1+1=~5~false the question 2 invalid~0 20201103 Tom: 0 0~0 输入样例4: 简单测试,含试卷无效题目的引用信息以及删除题目信息(由于题目本身无效,忽略)。例如: #N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 #T:1 1-5 3-8 #X:20201103 Tom-20201104 Jack-20201105 Www #S:1 20201103 #A:1-5 #A:2-4 #D:N-2 end 输出样例4: 输出不存在的题目提示信息。例如: alert: full score of test paper1 is not 100 points 1+1=~5~false non-existent question~0 20201103 Tom: 0 0~0 输入样例5: 综合测试,含错误格式输入、有效删除以及无效题目引用信息。例如: #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 #A:2-4 #D:N-2 end 输出样例5: 在这里给出相应的输出。例如: 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 输入样例6: 综合测试,含错误格式输入、有效删除、无效题目引用信息以及答案没有输入的情况。例如: #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 输出样例6: 答案没有输入的优先级最高。例如: 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 输入样例7: 综合测试,正常输入,含删除信息。例如: #N:2 #Q:2+2= #A:4 #N:1 #Q:1+1= #A:2 #T:1 1-5 2-8 #X:20201103 Tom-20201104 Jack-20201105 Www #S:1 20201103 #A:2-4 #A:1-5 #D:N-2 end 输出样例7: 例如: alert: full score of test paper1 is not 100 points 1+1=~5~false the question 2 invalid~0 20201103 Tom: 0 0~0 输入样例8: 综合测试,无效的试卷引用。例如: #N:1 #Q:1+1= #A:2 #T:1 1-5 #X:20201103 Tom #S:2 20201103 #A:1-5 #A:2-4 end 输出样例8: 例如: alert: full score of test paper1 is not 100 points The test paper number does not exist 输入样例9: 无效的学号引用。例如: #N:1 #Q:1+1= #A:2 #T:1 1-5 #X:20201106 Tom #S:1 20201103 #A:1-5 #A:2-4 end 输出样例9: 答案照常输出,判分时提示错误。例如: alert: full score of test paper1 is not 100 points 1+1=~5~false 20201103 not found 输入样例10: 信息可打乱顺序输入:序号不是按大小排列,各类信息交错输入。但本题不考虑引用的题目在被引用的信息之后出现的情况(如试卷引用的所有题目应该在试卷信息之前输入),所有引用的数据应该在被引用的信息之前给出。例如: #N:3 #Q:中国第一颗原子弹的爆炸时间 #A:1964.10.16 #N:1 #Q:1+1= #A:2 #X:20201103 Tom-20201104 Jack-20201105 Www #T:1 1-5 3-8 #N:2 #Q:2+2= #A:4 #S:1 20201103 #A:1-5 #A:2-4 end 输出样例10: 答案按试卷中的题目顺序输出。例如: alert: full score of test paper1 is not 100 points 1+1=~5~false 中国第一颗原子弹的爆炸时间~4~false 20201103 Tom: 0 0~0
题目有点长,先说总要吧:
1、模拟场景:多张试卷、多张答卷的信息处理,
新增:学生信息、删除题目信息以及多种异常输入的监测,如答案为空字符、仅
有学生信息没有答案内容的空白卷、试卷引用、试题引用错误等。
2、详细内容:a、输入试题的信息(编号、题目、标准答案)、试卷引用信息(试卷号、引用的题目号-分值)、答卷信息(试卷号、答案)、学生信息(学号、姓名)、删除题目信息(题号)
b、输出试题每一题的答题、判题信息以及最后每一题的判分结果、总分。输入中出现各类错误时输出对应错误信息
接下来详细分析:
1、题目信息 题目信息为独行输入,一行为一道题,多道题可分多行输入。 格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案 格式约束: 1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。 2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。 样例:#N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 2、试卷信息 试卷信息为独行输入,一行为一张试卷,多张卷可分多行输入数据。 格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值+" "+题目编号+"-"+题目分值+... 格式约束: 题目编号应与题目信息中的编号对应。 一行信息中可有多项题目编号与分值。 样例:#T:1 3-5 4-8 5-2
这两个都是和题集2的差不多的
3、学生信息 学生信息只输入一行,一行中包括所有学生的信息,每个学生的信息包括学号和姓名,格式如下。 格式:"#X:"+学号+" "+姓名+"-"+学号+" "+姓名....+"-"+学号+" "+姓名 格式约束: 答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。 样例: #S:1 #A:5 #A:22 1是试卷号 5是1号试卷的顺序第1题的题目答案
新加的学生信息,有学生和学号,记得仔细看格式!
4、答卷信息 答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序号与试 卷信息中的题目顺序相对应。答卷中: 格式:"#S:"+试卷号+" "+学号+" "+"#A:"+试卷题目的顺序号+"-"+答案内容+... 格式约束: 答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。 答案内容可以为空,即””。 答案内容中如果首尾有多余的空格,应去除后再进行判断。 样例: #T:1 1-5 3-2 2-5 6-9 4-10 7-3 #S:1 20201103 #A:2-5 #A:6-4 1是试卷号 20201103是学号 2-5中的2是试卷中顺序号,5是试卷第2题的答案,即T中3-2的答案 6-4中的6是试卷中顺序号,4是试卷第6题的答案,即T中7-3的答案 注意:不要混淆顺序号与题号
答题信息也是改变了很多,这个要仔细读题,然后就是他匹配的情况是什么,这上面也解释清楚了。
5、删除题目信息 删除题目信息为独行输入,每一行为一条删除信息,多条删除信息可分多行输入。该信息用于删除一道题目信息,题目被删除之后,引用该题目的试卷依然有效,但被删除的题目将以0分计,同时在输出答案时,题目内容与答案改为一条失效提示,例如:”the question 2 invalid~0” 格式:"#D:N-"+题目号 格式约束: 题目号与第一项”题目信息”中的题号相对应,不是试卷中的题目顺序号。 本题暂不考虑删除的题号不存在的情况。 样例: #N:1 #Q:1+1= #A:2 #N:2 #Q:2+2= #A:4 #T:1 1-5 2-8 #X:20201103 Tom-20201104 Jack #S:1 20201103 #A:1-5 #A:2-4 #D:N-2 end 输出 alert: full score of test paper1 is not 100 points 1+1=~5~false the question 2 invalid~0 20201103 Tom: 0 0~0 答题信息以一行"end"标记结束,"end"之后的信息忽略。
这个是而外新加的,特别要注意的点是删除完之后要输出特殊的语句,这个是重点。
3、判分信息 判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。 格式:**学号+" "+姓名+": "**+题目得分+" "+....+题目得分+"~"+总分 格式约束: 1、没有输入答案的题目、被删除的题目、答案错误的题目计0分 2、判题信息的顺序与输入答题信息中的顺序相同 样例:20201103 Tom: 0 0~0 根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。 4、被删除的题目提示信息 当某题目被试卷引用,同时被删除时,答案中输出提示信息。样例见第5种输入信息“删除题目信息”。 5、题目引用错误提示信息 试卷错误地引用了一道不存在题号的试题,在输出学生答案时,提示”non-existent question~”加答案。例如: 输入: #N:1 #Q:1+1= #A:2 #T:1 3-8 #X:20201103 Tom-20201104 Jack-20201105 Www #S:1 20201103 #A:1-4 end 输出: alert: full score of test paper1 is not 100 points non-existent question~0 20201103 Tom: 0~0 如果答案输出时,一道题目同时出现答案不存在、引用错误题号、题目被删除,只提示一种信息,答案不存在的优先级最高,例如: 输入: #N:1 #Q:1+1= #A:2 #T:1 3-8 #X:20201103 Tom-20201104 Jack-20201105 Www #S:1 20201103 end 输出: alert: full score of test paper1 is not 100 points answer is null 20201103 Tom: 0~0 6、格式错误提示信息 输入信息只要不符合格式要求,均输出”wrong format:”+信息内容。 例如:wrong format:2 #Q:2+2= #4 7、试卷号引用错误提示输出 如果答卷信息中试卷的编号找不到,则输出”the test paper number does not exist”,答卷中的答案不用输出,参见样例8。 8、学号引用错误提示信息 如果答卷中的学号信息不在学生列表中,答案照常输出,判分时提示错误。参见样例9。
这个输出信息中加上第二题集的条件,其他的条件就是:
1、判分的时候要加上学号和姓名
2、就是上面说的删除情况
3、题目引用错误的时候要输出特殊语句 我在这里就踩了坑
4、格式错误要输出特殊wrong format格式,这个就是正则表达式判断
5、学号引用错误要输出特殊格式
接下来就是我的答题代码:
1 import java.util.ArrayList; 2 import java.util.Scanner; 3 import java.util.regex.Matcher; 4 import java.util.regex.Pattern; 5 6 class Main { 7 8 public static void main(String[] args) { 9 // TODO 自动生成的方法存根 10 11 Scanner in = new Scanner(System.in); 12 13 ArrayList<String> lines = new ArrayList<String>();//用来储存全部输入 14 ArrayList<String> lineN = new ArrayList<String>();//这个是带N的行输入,如果说lines中有带N的元素,就方在这里面,但是要符合。 15 ArrayList<String> lineT = new ArrayList<String>();//这个是带T 16 ArrayList<String> lineX = new ArrayList<String>();//带X 17 ArrayList<String> lineS = new ArrayList<String>();//带S 18 ArrayList<String> lineD = new ArrayList<String>();//带D 19 ArrayList<String> line1 = new ArrayList<String>();//这是不符合要求的元素 20 21 ArrayList<String> lineNcontent = new ArrayList<String>();//N全存 22 ArrayList<String> lineXid = new ArrayList<String>();//X的学号 23 ArrayList<String> lineXname = new ArrayList<String>();//X的姓名 24 ArrayList<String> lineDdelete = new ArrayList<String>();//D中的删除 25 26 //上面全是定义的List数组 27 28 Match match = new Match();//匹配的类 29 SplitArray splitArray = new SplitArray(lineN , lineT , lineX , lineS , lineD);//分割的类 30 31 while(true) {//把所有输入都放进一个变长数组中 32 String str = in.nextLine(); 33 if(str.equals("end")) { 34 break; 35 } 36 lines.add(str); 37 } 38 39 for(int i = 0 ; i < lines.size() ; i ++ ) { 40 if(match.judgeN(lines.get(i))) { 41 lineN.add(lines.get(i)); 42 continue; 43 } 44 if(match.judgeT(lines.get(i))) { 45 lineT.add(lines.get(i)); 46 continue; 47 } 48 if(match.judgeX(lines.get(i))) { 49 lineX.add(lines.get(i)); 50 continue; 51 } 52 if(match.judgeS(lines.get(i))) { 53 lineS.add(lines.get(i)); 54 continue; 55 } 56 if(match.judgeD(lines.get(i))) { 57 lineD.add(lines.get(i)); 58 continue; 59 } 60 else { 61 line1.add(lines.get(i)); 62 if(line1.size() != 0) { 63 System.out.println("wrong format:" + line1.get(line1.size() - 1)); 64 } 65 } 66 }//这个可以直接将错误的踢出并且按要求放进数组中 67 68 //接下来把上面符合的都分割了。 69 splitArray.SplitlineN(lineNcontent); 70 splitArray.SplitlineX1(lineXid); 71 splitArray.SplitlineX2(lineXname); 72 splitArray.SplitlineD(lineDdelete); 73 74 int b = 0; 75 for(int i = 0 ; i < lineS.size() ; i ++) { 76 ArrayList<String> lineScontent = new ArrayList<String>();//分别储存每一个 77 ArrayList<String> lineSquestion = new ArrayList<String>(); 78 ArrayList<String> lineSanswer = new ArrayList<String>(); 79 splitArray.SplitlineS1(lineScontent, i); 80 splitArray.SplitlineS2(lineScontent, lineSquestion); 81 splitArray.SplitlineS3(lineScontent, lineSanswer); 82 83 84 85 for(int j = 0 ; j < lineT.size() ; j ++) { 86 ArrayList<String> lineTcontent = new ArrayList<String>();//T先分 87 ArrayList<String> lineTquestion = new ArrayList<String>();//T分后的题目 88 ArrayList<String> lineTscore = new ArrayList<String>();//T分后的分数 89 splitArray.SplitlineT1(lineTcontent , j); 90 splitArray.SplitlineT2(lineTcontent , lineTquestion); 91 splitArray.SplitlineT3(lineTcontent , lineTscore); 92 93 Body body = new Body(lineNcontent,lineTcontent,lineTquestion,lineTscore,lineXid,lineXname,lineScontent,lineSquestion,lineSanswer,lineDdelete); 94 body.judgesocer(); 95 if(!lineScontent.get(0).equals(lineTcontent.get(0))) { 96 b ++; 97 if(b != lineT.size() - 1 && lineT.size() != 1) { 98 continue; 99 }if(b == lineT.size() - 1) { 100 System.out.println("The test paper number does not exist"); 101 }if(lineT.size() == 1 && b == lineT.size()) { 102 System.out.println("The test paper number does not exist"); 103 } 104 } else if(lineScontent.get(0).equals(lineTcontent.get(0))) { 105 106 body.judgeAll(); 107 break; 108 } 109 } 110 111 break; 112 } 113 } 114 115 } 116 117 class Question { 118 private String num; 119 private String content; 120 private String standard; 121 122 public Question() { 123 // TODO 自动生成的构造函数存根 124 } 125 126 public Question(String num, String content, String standard) { 127 super(); 128 this.num = num; 129 this.content = content; 130 this.standard = standard; 131 } 132 133 public String getNum() { 134 return num; 135 } 136 137 public void setNum(String num) { 138 this.num = num; 139 } 140 141 public String getContent() { 142 return content; 143 } 144 145 public void setContent(String content) { 146 this.content = content; 147 } 148 149 public String getStandard() { 150 return standard; 151 } 152 153 public void setStandard(String standard) { 154 this.standard = standard; 155 } 156 157 } 158 159 class Paper { 160 private String inputall; 161 162 public Paper() { 163 // TODO 自动生成的构造函数存根 164 } 165 166 public Paper(String inputall) { 167 super(); 168 this.inputall = inputall; 169 } 170 171 public String getInputall() { 172 return inputall; 173 } 174 175 public void setInputall(String inputall) { 176 this.inputall = inputall; 177 } 178 179 } 180 181 182 class Papersplit { 183 private String paper; 184 185 public Papersplit() { 186 // TODO 自动生成的构造函数存根 187 } 188 189 public Papersplit(String paper) { 190 super(); 191 this.paper = paper; 192 } 193 194 public String getPaper() { 195 return paper; 196 } 197 198 public void setPaper(String paper) { 199 this.paper = paper; 200 } 201 202 public String[] Split(String[] c) { 203 String[] b = paper.split("#T:|\\s|-"); 204 for(int i = 1 ; i < b.length ; i ++) { 205 c[i - 1] = b[i]; 206 } 207 return c; 208 } 209 210 } 211 212 213 class Student { 214 private String inputall; 215 216 public Student() { 217 // TODO 自动生成的构造函数存根 218 } 219 220 public Student(String inputall) { 221 super(); 222 this.inputall = inputall; 223 } 224 225 public String getInputall() { 226 return inputall; 227 } 228 229 public void setInputall(String inputall) { 230 this.inputall = inputall; 231 } 232 233 } 234 235 236 class StudentSplit { 237 private String student; 238 239 public StudentSplit() { 240 // TODO 自动生成的构造函数存根 241 } 242 243 public StudentSplit(String student) { 244 super(); 245 this.student = student; 246 } 247 248 public String getStudent() { 249 return student; 250 } 251 252 public void setStudent(String student) { 253 this.student = student; 254 } 255 256 public String[] Split(String[] b) { 257 String[] a = student.split("\\s|-|#X:"); 258 for(int i = 1 ; i < a.length ; i ++ ) { 259 b[i - 1] = a[i]; 260 } 261 return b; 262 } 263 } 264 265 266 class Delete { 267 private String inputall; 268 269 public Delete() { 270 // TODO 自动生成的构造函数存根 271 } 272 273 public Delete(String inputall) { 274 super(); 275 this.inputall = inputall; 276 } 277 278 public String getInputall() { 279 return inputall; 280 } 281 282 public void setInputall(String inputall) { 283 this.inputall = inputall; 284 } 285 286 } 287 288 289 class DeleteSplit { 290 private String delete; 291 292 public DeleteSplit() { 293 // TODO 自动生成的构造函数存根 294 } 295 296 public DeleteSplit(String delete) { 297 super(); 298 this.delete = delete; 299 } 300 301 public String getDelete() { 302 return delete; 303 } 304 305 public void setDelete(String delete) { 306 this.delete = delete; 307 } 308 309 public String Split() { 310 String[] b = delete.split("\\s|#D:|N-"); 311 return b[1]; 312 } 313 } 314 315 316 class Test { 317 private String inputall; 318 319 public Test() { 320 // TODO 自动生成的构造函数存根 321 } 322 323 public Test(String inputall) { 324 super(); 325 this.inputall = inputall; 326 } 327 328 public String getInputall() { 329 return inputall; 330 } 331 332 public void setInputall(String inputall) { 333 this.inputall = inputall; 334 } 335 336 } 337 338 339 class TestSplit { 340 private String test; 341 342 public TestSplit() { 343 // TODO 自动生成的构造函数存根 344 } 345 346 public TestSplit(String test) { 347 super(); 348 this.test = test; 349 } 350 351 public String getTest() { 352 return test; 353 } 354 355 public void setTest(String test) { 356 this.test = test; 357 } 358 359 public String[] Split(String[] b) { 360 String[] a = test.split("\\s|-|#S:|#A:"); 361 for(int i = 1 ; i < a.length ; i ++) { 362 b[i - 1] = a[i]; 363 } 364 return b; 365 } 366 } 367 368 369 class Match { 370 371 public Match() { 372 // TODO 自动生成的构造函数存根 373 } 374 375 public boolean judgeN(String line) { 376 String regex = "#N:\\s*(\\d+)\\s*#Q:\\s*(.*?)\\s*#A:\\s*(.*?)\\s*"; 377 Pattern pattern = Pattern.compile(regex); 378 Matcher matcher = pattern.matcher(line); 379 if(matcher.matches()) { 380 return true; 381 } else { 382 return false; 383 } 384 } 385 386 public boolean judgeT(String line) { 387 String regex = "^#T:( )*\\d+( )*((\\d+(( )*)-(( )*)\\d+( )*)+)$"; 388 Pattern pattern = Pattern.compile(regex); 389 Matcher matcher = pattern.matcher(line); 390 if(matcher.matches()) { 391 return true; 392 } else { 393 return false; 394 } 395 } 396 397 public boolean judgeX(String line) { 398 String regex = "^#X:\\s*\\d+\\s(\\w+)+(?:-\\d+\\s\\w+)*$"; 399 Pattern pattern = Pattern.compile(regex); 400 Matcher matcher = pattern.matcher(line); 401 if(matcher.matches()) { 402 return true; 403 } else { 404 return false; 405 } 406 } 407 408 public boolean judgeS(String line) { 409 String regex = "^#S:( )*\\d+( )*\\d+\\s*(.*?)$"; 410 Pattern pattern = Pattern.compile(regex); 411 Matcher matcher = pattern.matcher(line); 412 if(matcher.matches()) { 413 return true; 414 } else { 415 return false; 416 } 417 } 418 419 public boolean judgeD(String line) { 420 String regex = "^#D:\\s*N\\s*-\\s*\\d+( )*$"; 421 Pattern pattern = Pattern.compile(regex); 422 Matcher matcher = pattern.matcher(line); 423 if(matcher.matches()) { 424 return true; 425 } else { 426 return false; 427 } 428 } 429 430 } 431 432 class SplitArray { 433 private String[] temp = new String[1000];//这个是创建中间的变量。 434 private ArrayList<String> lineN; 435 private ArrayList<String> lineT; 436 private ArrayList<String> lineX; 437 private ArrayList<String> lineS; 438 private ArrayList<String> lineD; 439 440 public SplitArray() { 441 super(); 442 // TODO 自动生成的构造函数存根 443 } 444 445 public SplitArray(ArrayList<String> lineN, ArrayList<String> lineT, ArrayList<String> lineX, 446 ArrayList<String> lineS, ArrayList<String> lineD) { 447 super(); 448 this.lineN = lineN; 449 this.lineT = lineT; 450 this.lineX = lineX; 451 this.lineS = lineS; 452 this.lineD = lineD; 453 } 454 455 public ArrayList<String> SplitlineN(ArrayList<String> lineNcontent) {//将N的分为全存的 456 for(int i = 0 ; i < lineN.size() ; i ++) { 457 temp = lineN.get(i).split("\\s|#N:|#Q:|#A:"); 458 for(int j = 1 ; j < temp.length ; j += 2 ) {//改成+=2 459 lineNcontent.add(temp[j]); 460 } 461 } 462 return lineNcontent; 463 } 464 465 public ArrayList<String> SplitlineT1(ArrayList<String> lineTcontent , int n) {//将T的先分 466 temp = lineT.get(n).split("\\s|#T:"); 467 for(int j = 1 ; j < temp.length ; j ++ ) { 468 lineTcontent.add(temp[j]); 469 } 470 return lineTcontent; 471 } 472 473 public ArrayList<String> SplitlineT2(ArrayList<String> lineTcontent , ArrayList<String> lineTquestion){//分出T题目号 474 for(int i = 1 ; i < lineTcontent.size() ; i ++ ) { 475 temp = lineTcontent.get(i).split("-"); 476 lineTquestion.add(temp[0]); 477 } 478 return lineTquestion; 479 } 480 481 public ArrayList<String> SplitlineT3(ArrayList<String> lineTcontent , ArrayList<String> lineTscore){//分出T分数 482 for(int i = 1 ; i < lineTcontent.size() ; i ++ ) { 483 temp = lineTcontent.get(i).split("-"); 484 lineTscore.add(temp[1]); 485 } 486 return lineTscore; 487 } 488 489 public ArrayList<String> SplitlineX1(ArrayList<String> lineXid) {//分出学号 490 temp = lineX.get(0).split("\\s|#X:|-"); 491 for(int i = 1 ; i < temp.length ; i += 2 ) { 492 lineXid.add(temp[i]); 493 } 494 return lineXid; 495 } 496 497 public ArrayList<String> SplitlineX2(ArrayList<String> lineXname) {//分出姓名 498 temp = lineX.get(0).split("\\s|#X:|-"); 499 for(int i = 2 ; i < temp.length ; i += 2 ) { 500 lineXname.add(temp[i]); 501 } 502 return lineXname; 503 } 504 505 public ArrayList<String> SplitlineS1(ArrayList<String> lineScontent , int n) { 506 507 temp = lineS.get(n).split("\\s+|#S:|#A:"); 508 for(int i = 1 ; i < temp.length ; i ++) { 509 if(i <= 2) { 510 lineScontent.add(temp[i]); 511 } 512 if(i >= 4) { 513 lineScontent.add(temp[i]); 514 i ++; 515 } 516 } 517 return lineScontent; 518 } 519 520 public ArrayList<String> SplitlineS2(ArrayList<String> lineScontent , ArrayList<String> lineSquestion) {//S里的题目 521 for(int i = 2 ; i < lineScontent.size() ; i ++ ) { 522 temp = lineScontent.get(i).split("-"); 523 524 for(int j = 2 ; j < lineScontent.size() ; j ++) { 525 lineSquestion.add(temp[0]); 526 break; 527 } 528 } 529 return lineSquestion; 530 } 531 532 public ArrayList<String> SplitlineS3(ArrayList<String> lineScontent , ArrayList<String> lineSanswer) {//S里的题目 533 for(int i = 2 ; i < lineScontent.size() ; i ++ ) { 534 temp = lineScontent.get(i).split("-"); 535 for(int j = 2 ; j < lineScontent.size() ; j ++) { 536 lineSanswer.add(temp[1]); 537 break; 538 } 539 } 540 return lineSanswer; 541 } 542 543 public ArrayList<String> SplitlineD(ArrayList<String> lineDdelete) {//分D的 544 for(int i = 0 ; i < lineD.size() ; i ++) { 545 temp = lineD.get(i).split("\\s|#N:|-"); 546 lineDdelete.add(temp[1]); 547 } 548 return lineDdelete; 549 } 550 } 551 552 553 554 555 556 class Body { 557 private ArrayList<String> lineNcontent = new ArrayList<String>();//N全存 558 private ArrayList<String> lineTcontent = new ArrayList<String>();//T先分 559 private ArrayList<String> lineTquestion = new ArrayList<String>();//T分后的题目 560 private ArrayList<String> lineTscore = new ArrayList<String>();//T分后的分数 561 private ArrayList<String> lineXid = new ArrayList<String>();//X的学号 562 private ArrayList<String> lineXname = new ArrayList<String>();//X的姓名 563 private ArrayList<String> lineScontent = new ArrayList<String>();//S的先分 564 private ArrayList<String> lineSquestion = new ArrayList<String>();//S的分后的题目 565 private ArrayList<String> lineSanswer = new ArrayList<String>();//S分后的答案 566 private ArrayList<String> lineDdelete = new ArrayList<String>();//D中的删除 567 568 public Body(ArrayList<String> lineNcontent, ArrayList<String> lineTcontent, ArrayList<String> lineTquestion, 569 ArrayList<String> lineTscore, ArrayList<String> lineXid, ArrayList<String> lineXname, 570 ArrayList<String> lineScontent, ArrayList<String> lineSquestion, ArrayList<String> lineSanswer, 571 ArrayList<String> lineDdelete) { 572 super(); 573 this.lineNcontent = lineNcontent; 574 this.lineTcontent = lineTcontent; 575 this.lineTquestion = lineTquestion; 576 this.lineTscore = lineTscore; 577 this.lineXid = lineXid; 578 this.lineXname = lineXname; 579 this.lineScontent = lineScontent; 580 this.lineSquestion = lineSquestion; 581 this.lineSanswer = lineSanswer; 582 this.lineDdelete = lineDdelete; 583 } 584 585 public ArrayList<String> findwhere(ArrayList<String> n) {//找到试卷在那个T中的位置 586 for(int i = 0 ; i < lineTcontent.size() ; i++ ) { 587 if(!lineTcontent.get(i).matches("-")) { 588 n.add(String.valueOf(i)); 589 } 590 } 591 return n; 592 } 593 594 public void judgesocer() {//判断分数 595 ArrayList<String> n = new ArrayList<String>(); 596 findwhere(n); 597 int sum = 0; 598 for(int j = 0 ; j < n.size() ; j ++) { 599 for(int i = 0 ; i < lineTscore.size() ; i ++) { 600 sum += Integer.parseInt(lineTscore.get(i)); 601 } 602 } 603 if(sum != 100) { 604 System.out.println("alert: full score of test paper" + 1 + " is not 100 points"); 605 } 606 } 607 608 public void judgeD() {//判断删除的,标记 609 for(int i = 0 ; i < lineDdelete.size() ; i ++) { 610 for(int j = 0 ; j < lineNcontent.size() ; j += 3) { 611 if(lineDdelete.get(i).equals(lineNcontent.get(j))) { 612 lineNcontent.set(j , "no"); 613 } 614 } 615 } 616 } 617 618 public void backD() { 619 ArrayList<String> lineplace = new ArrayList<String>(); 620 for(int i = 0 ; i < lineDdelete.size() ; i ++) { 621 for(int j = 0 ; j < lineNcontent.size() ; j += 3) { 622 if(lineNcontent.get(j).equals("no")) { 623 lineplace.add(lineDdelete.get(i)); 624 } 625 } 626 } 627 if(lineNcontent.contains("no")) { 628 for(int j = 0 ; j < lineplace.size() ; ) { 629 for(int i = 0 ; i < lineNcontent.size() ; i += 3) { 630 if(lineNcontent.get(i).equals("no")) { 631 lineNcontent.set(i, lineplace.get(j)); 632 j ++; 633 break; 634 } 635 } 636 } 637 } 638 639 } 640 641 public void sortTquestion() { 642 int[] n = new int[lineSquestion.size()]; 643 int[] m = new int[lineSanswer.size()]; 644 for(int i = 0 ; i < lineSquestion.size() ; i ++) { 645 n[i] = Integer.parseInt(lineSquestion.get(i)); 646 } 647 for(int i = 0 ; i < lineSanswer.size() ; i ++) { 648 m[i] = Integer.parseInt(lineSanswer.get(i)); 649 } 650 for(int i = 0 ; i < n.length - 1 ; i ++) { 651 for(int j = i + 1 ; j < n.length ; j ++) { 652 if(n[i] > n[j]) { 653 int temp = n[i]; 654 n[i] = n[j]; 655 n[j] = temp; 656 int t = m[i]; 657 m[i] = m[j]; 658 m[j] = t; 659 } 660 } 661 } 662 for(int i = 0 ; i < n.length ; i++) { 663 lineSquestion.set(i , String.valueOf(n[i])); 664 } 665 for(int i = 0 ; i < m.length ; i ++ ) { 666 lineSanswer.set(i, String.valueOf(m[i])); 667 } 668 } 669 670 public void sortN() { 671 int[] n = new int[lineNcontent.size() / 3]; 672 String[] m = new String[lineNcontent.size() / 3]; 673 String[] k = new String[lineNcontent.size() / 3]; 674 for(int i = 0 ; i < lineNcontent.size() / 3 ; i ++) { 675 n[i] = Integer.parseInt(lineNcontent.get(i * 3)); 676 } 677 for(int i = 0 ; i < lineNcontent.size() / 3 ; i ++) { 678 m[i] = lineNcontent.get(i * 3 + 1); 679 } 680 for(int i = 0 ; i < lineNcontent.size() / 3 ; i ++) { 681 k[i] = lineNcontent.get(i * 3 + 2); 682 } 683 for(int i = 0 ; i < n.length - 1 ; i ++) { 684 for(int j = i + 1 ; j < n.length ; j ++) { 685 if(n[i] > n[j]) { 686 int temp = n[i]; 687 n[i] = n[j]; 688 n[j] = temp; 689 String t = m[i]; 690 m[i] = m[j]; 691 m[j] = t; 692 String t1 = k[i]; 693 k[i] = k[j]; 694 k[j] = t1; 695 } 696 } 697 } 698 for(int i = 0 ; i < n.length ; i ++) { 699 lineNcontent.set(i * 3, String.valueOf(n[i])); 700 } 701 for(int i = 0 ; i < m.length ; i ++) { 702 lineNcontent.set(i * 3 + 1, m[i]); 703 } 704 for(int i = 0 ; i < k.length ; i ++ ) { 705 lineNcontent.set(i * 3 + 2, k[i]); 706 } 707 } 708 709 public void judgeAll() { 710 sortN(); 711 712 713 sortTquestion(); 714 715 ArrayList<String> score = new ArrayList<String>();//统计分数 716 int sum = 0; 717 for(int i = 0 ; i < lineTquestion.size() ; i ++) { 718 int x = 0; 719 backD(); 720 for(int i1 = 0 ; i1 < lineTquestion.size() ; i1 ++) { 721 if(lineNcontent.size() == 3) { 722 if(Integer.parseInt( lineTquestion.get(i)) > Integer.parseInt(lineNcontent.get(0))) { 723 x ++; 724 } 725 726 } else { 727 if(Integer.parseInt( lineTquestion.get(i)) > Integer.parseInt(lineNcontent.get(i * 3))) { 728 x ++; 729 } 730 } 731 732 } 733 judgeD(); 734 if(lineNcontent.size() == 3) { 735 if(i == 0) { 736 if(lineNcontent.get(0).equals("no") && x == lineNcontent.size() / 3 ) { 737 System.out.println("the question " + (i + 1) + " invalid~0"); 738 // score.add("0"); 739 }else if(!lineNcontent.get(0).equals("no") && x == lineNcontent.size() / 3) { 740 for(int j = 0 ; j < lineSquestion.size() ; j ++) { 741 if(i + 1 == Integer.parseInt(lineTquestion.get(i))) { 742 if(lineSanswer.get(j).equals(lineNcontent.get(Integer.parseInt(lineTquestion.get(i)) + 1))) { 743 System.out.println(lineNcontent.get(Integer.parseInt(lineTquestion.get(i))) + "~" + lineSanswer.get(j) + "~true"); 744 score.add(lineTscore.get(i)); 745 break; 746 } else { 747 System.out.println(lineNcontent.get(Integer.parseInt(lineTquestion.get(i))) + "~" + lineSanswer.get(j) + "~false"); 748 score.add("0"); 749 break; 750 } 751 } else { 752 System.out.println("answer is null"); 753 } 754 } 755 } 756 if(x != lineNcontent.size() / 3) { 757 System.out.println("non-existent question~0"); 758 score.add("0"); 759 } 760 } else { 761 if(lineNcontent.get(0).equals("no") && x == 0 ) { 762 System.out.println("the question " + (i + 1) + " invalid~0"); 763 // score.add("0"); 764 }else if(!lineNcontent.get(0).equals("no") && x == 0) { 765 for(int j = 0 ; j < lineSquestion.size() ; j ++) { 766 if(i + 1 == Integer.parseInt(lineTquestion.get(i))) { 767 if(lineSanswer.get(j).equals(lineNcontent.get(Integer.parseInt(lineTquestion.get(i)) + 1))) { 768 System.out.println(lineNcontent.get(Integer.parseInt(lineTquestion.get(i))) + "~" + lineSanswer.get(j) + "~true"); 769 score.add(lineTscore.get(i)); 770 break; 771 } else { 772 System.out.println(lineNcontent.get(Integer.parseInt(lineTquestion.get(i))) + "~" + lineSanswer.get(j) + "~false"); 773 score.add("0"); 774 break; 775 } 776 } else { 777 System.out.println("answer is null"); 778 } 779 } 780 } 781 if(x != 0 ) { 782 System.out.println("non-existent question~0"); 783 score.add("0"); 784 } 785 } 786 } else { 787 if(lineNcontent.get(3 * i).equals("no") && x == 0) { 788 System.out.println("the question " + (i + 1) + " invalid~0"); 789 // score.add("0"); 790 }else if(!lineNcontent.get(3 * i).equals("no") && x == 0) { 791 for(int j = 0 ; j < lineSquestion.size() ; j ++) { 792 if(i + 1 == Integer.parseInt(lineTquestion.get(i))) { 793 if(lineSanswer.get(j).equals(lineNcontent.get(Integer.parseInt(lineTquestion.get(i)) + 1))) { 794 System.out.println(lineNcontent.get(Integer.parseInt(lineTquestion.get(i))) + "~" + lineSanswer.get(j) + "~true"); 795 score.add(lineTscore.get(i)); 796 break; 797 } else { 798 System.out.println(lineNcontent.get(Integer.parseInt(lineTquestion.get(i))) + "~" + lineSanswer.get(j) + "~false"); 799 score.add("0"); 800 break; 801 } 802 } else { 803 System.out.println("answer is null"); 804 } 805 } 806 } 807 if(x != 0 ) { 808 System.out.println("non-existent question~0"); 809 score.add("0"); 810 } 811 } 812 813 814 } 815 816 for(int i = 0 ; i < score.size() ; i ++) { 817 sum += Integer.parseInt(score.get(i)); 818 } 819 820 int a = 0; 821 for(int i = 0 ; i < lineXid.size() ; i ++) { 822 if(lineXid.get(i).equals(lineScontent.get(1))) { 823 System.out.print(lineXid.get(i) + " " + lineXname.get(i) + ":"); 824 for(int j = 0 ; j < lineTquestion.size() ; j ++) { 825 System.out.print(" " + score.get(i)); 826 } 827 System.out.println("~" + sum); 828 break; 829 } else { 830 a ++; 831 if(a != lineXid.size() - 1 && lineXid.size() != 1) { 832 continue; 833 }if(a == lineXid.size() - 1) { 834 System.out.println(lineScontent.get(1) + " not found"); 835 }if(a == lineXid.size() && lineXid.size() == 1) { 836 System.out.println(lineScontent.get(1) + " not found"); 837 } 838 } 839 } 840 } 841 }
然后展示一下我的类图和数据:
在这里我就放了一个很大的错误,就是用了大量的if和for语句,这个在java的代码中是绝对不可取的,所以这个是我之后要重点改正的方面之一。
接下来是对于第三次题集的总结:
1、还是不能很好的遵循单一职责原则,老是会将一个类做两种事,这个 一定一定要严格改正。
2、就是对于类与类之间的关系还是不能很好的联系在一起,这个要好好学设计,多请教同学。
3、对于一些逻辑的问题还是会有问题,比如说这个题集的第2题。还有第三题的逻辑也有问题,所以在写之前就是要我们好好考虑之后再进行编码,在这之前要好好想一想这样写对于之后的影响是什么。