一.前言
知识点考查和难度:
题目集一第一题
设计风扇Fan类考查了Java类的组成部分和具体的组成内容。
题目集一第二题
巩固了类和对象的使用,和其中的构造方法。
题目集一第三题
在第二题考查基础上添加了具体的方法。
题目集一第四题
进一步学习类的使用,做了简单的关联类体现数据的交互
题目集一第五题
判题程序,综合使用类,以及简单考查了字符串的输入与分组,不同类之间的关联和方法调用。
题目集一主要还是Java面向对象的引入和巩固,对类的一个使用学习,难度只在判题程序一体现,不仅要思考几个大类和其中包含的数据,更要求我们找到类之间的交错联系,还考查输入输出格式的一个固定。
题目集二第一题
手机排序查找,要求重写compare_to方法考查接口的使用,和具体的输出格式要求。
题目集二第二题
圆的面积,类的基础使用,这题主要提醒我们在参数初始化的时候注意实际意义,如圆的半径>0。
题目集二第三题
汽车类,以填空形式考查类的基础使用
题目集二第四题
判题程序二,在判题程序一基础上增加了新类试卷类,考查了对类的综合分析和使用,数据的对应匹配的编写方法。
题目集二对类的使用较于题目集一更加综合,新学习了接口的使用和如何重写接口的方法,对接口有了初步的了解,难度也主要体现在判题程序,对类之间的关系更加深刻,对数据匹配重点考查,如何一一对应,难度升高。
题目集三第一题
考查封装性,展示了封装好的类的实例
题目集三第二题
日期类的基本使用,考查了对日期的换算,日期的相关函数编写(对日期函数的使用),但是我是自己按逻辑编写的日期函数,没有用库函数。
题目集三第三题
判题程序三,在判题程序二基础上新增删除题目信息和学生的输入形式,综合考查了逻辑能力,输入输出格式分解,和类的交互使用,
题目集三总体进一步综合考查类的交互使用,以及新增方法后每个类之间的交互联系的改变,对数据的输入输出格式,类对象的分解难度加大,难度较大。
二.设计分析
因为题目集1~3中有部分题目是直接照题目按部就班写的代码,在此仅对部分题目做具体的设计分析。
1.题目集一第五题判题程序:
根据题目信息,题目逻辑为输入题目和答题信息,需要我们进行判断题,则需要获取题目的信息数据和作答答案进行比对,由于题目可以是多道,因而考虑答案和题目匹配情况,需要将题目存储在一起,并且有序排列。由此可设计分为题目类Question用于表示单个题目,包括题号、题目内容和标准答案。试卷类Paper:表示一张试卷,包含一个存储对象的列表和试卷的题目数量。答题纸类AnswerSheet类表示答题纸,它依赖于Paper类,包含对对象的引用、存储用户答案的列表和存储判断结果的列表。
在主函数需要
首先从控制台读取题目数量,创建Paper对象用于表示试卷,循环读取每一道题目,解析题目信息,创建Question对象并保存到试卷中,创建AnswerSheet对象,用于处理答题信息,读取用户答案,直到输入end为止,将用户答案保存到答题纸中,循环输出每一道题目的题目内容和用户答案,最后输出判断结果字符串。
程序时序图如下:
2.题目集二第四题判题程序:
在判题程序一上首先打乱了题目信息,对试卷有了要求,一行为一张卷子,所以思考如何区分输入的内容是试卷信息还是答题信息,依据区别:前面的标识符,进行分割。然后答案数量可以不等于题目数量,需要我们舍弃多余答案。并且我们需要计算试卷的总分值,并给出不是100分试卷的提示,所以需要在试卷类添加分值。因而设计Question类保持原样,
Paper类用于表示一张试卷,包含试卷编号和题目列表(以键值对形式存储,键为题目编号,值为题目分值)。提供了构造方法用于初始化试卷,方法包括获取试卷编号、添加题目及分值、计算试卷总分值以及从输入字符串创建试卷对象并检查总分是否为 100 分的方法。
AnswerSheet类,代表答题纸,包含答题纸对应的试卷编号(tPaperId)和用户答案列表。提供了构造方法用于初始化答题纸,以及从输入字符串创建答题纸对象和添加答案的方法。
定义了三个静态集合分别存储题目、试卷和答题纸对象。
在main方法中,使用Scanner读取输入,直到输入end为止。对于每一行输入,调用JudgeprocessInput方法判断输入类型并进行相应处理,根据输入的起始字符串判断是题目、试卷还是答题纸,并调用相应的处理方法。Question、TestPaper和AnswerSheet方法分别用于处理题目、试卷和答题纸的输入,将其转换为相应的对象并存储到集合中。evaluateAllAnswer方法遍历所有答题纸,调用evaluateAnswer方法对每个答题纸进行评估。evaluateAnswer方法根据答题纸对应的试卷,检查试卷是否存在,然后遍历试卷中的题目,获取用户答案,判断答案是否正确,计算总分并生成结果列表。printResults方法用于输出评估结果,包括每个题目的结果以及总分和各题得分。
题目时序图如下:
3.题目集三第三题判题程序:
相较于上一次判题程序,输入信息中新增了学生信息,增加了删除信息的功能,我的设计思路首先就是区分输入的是哪个部分的信息,如何将删除的题目进行匹配也是设计的一个难点。 我的思路如下对于输入处理通过Scanner读取输入,判断输入的类型(题目信息、试卷信息、学生信息、答卷信息、删除信息)。根据输入的类型调用相应的处理函数。数据存储:使用List
主函数里设计读取输入、处理不同类型的信息、输出结果。包含多个处理方法和输出结果的方法。通过processQuestion方法:processTestPaper方法:processStudent方法:processAnswer方法:分别将不同符号开头的信息给分隔开。再通过类里的方法对分割开的信息进行处理。
程序时序图如下:
4.题目集三第二题date日期:
从输出结果开始设计思路:当年第几天、当月第几天、当周第几天,输出结束日期与起始日期之间的相差的天数、月数、年数。求当年第几天则要考虑经过多少月,当月第几天即date的天项,当周第几天就是星期几,可以考虑用已知周几和相差天数来求,正好对应上第二问的求相差天数。
时序图:
三.踩坑心得
题目集一第五题判题程序一
1.对于题目数量的输入处理较为简单,仅使用了Scanner的nextInt()方法来获取。然而,这忽视了用户可能输入不符合要求数值的情况,比如负数、小数或者以 0 开头的多位数(0 本身除外)。这种情况下,程序可能会在后续处理中出现错误或异常,因为这些非法输入无法正确表示题目数量。
解决方法:
try {
questionnum = Integer.parseInt(numInput);
if (questionnum <= 0 || (numInput.length() > 1 && numInput.charAt(0) == '0')) {
System.out.println("输入不合法");
} else {
break;
}
} catch (NumberFormatException e) {
System.out.println("输入格式错误。");
}
采用循环结构,不断读取用户输入,直至输入满足题目数量的格式要求,即必须是整数且最高位不为 0(若为多位数)。在循环内部,通过try-catch块捕捉异常,以处理非法的输入格式。若输入不符合要求,及时提示用户重新输入。
2.用split方法按照空格拆分时,产生错误的结果,使得提取的信息不准确。而且,对于题目输入顺序与题号不相关的情况,最初的代码未能妥善处理,导致存储题目信息时出现混乱,后续在使用题目信息时可能会出现无法正确匹配题号和内容的问题。
解决方法:
int nIndex = questionLine.indexOf("#N:");
int qIndex = questionLine.indexOf("#Q:");
int aIndex = questionLine.indexOf("#A:");
int questionNum = Integer.parseInt(questionLine.substring(nIndex + 3, qIndex - 1).trim());
String questionContent = questionLine.substring(qIndex + 3, aIndex - 1).trim();
String standardAnswer = questionLine.substring(aIndex + 3).trim();
Question question = new Question(questionNum, questionContent, standardAnswer);
运用indexOf方法准确找到#N:、#Q:和#A:的位置,然后依据这些位置提取相应的信息。对于题目内容和答案中的空格,在提取后进行trim处理,去除首尾的空白字符,确保信息的准确性。
题目集二第四题判题程序二
1.没有考虑清楚题目编号有缺失且输入顺序不固定,当按照顺序处理输入时,如果先遇到了依赖后续题号的操作,可能会出现错误。而且在关联试卷题目时,可能会因为题号不连续而难以准确匹配。
解决方法:
Map<Integer, Question> questions = new HashMap<>();
使用了Map<Integer, Question>来存储题目信息,其中键为题目编号。这样,无论题号的输入顺序如何,都可以通过编号快速准确地获取题目对象。
2.试卷信息中的题目编号需要与题目信息中的编号对应,但可能存在输入错误的情况,即试卷中引用了不存在的题目编号。这会导致在后续关联题目和判题时出现问题,无法正确找到对应的题目内容和标准答案。
解决方法:
// 检查题目编号是否存在
if (!questions.containsKey(questionId)) {
System.out.println("试卷信息可能有误。");
continue; // 可以选择继续处理下一个题目-分值对,或者直接跳出循环等其他处理方式
}
testPaper.addQuestion(questionId, score);
testPapers.put(paperId, testPaper);
} else if (paperLine.equals("end")) {
break;
}
在处理试卷信息时,每次添加题目到试卷时,立即检查题目编号是否在已存储的题目信息Map中存在。如果不存在,给出错误提示并可以选择忽略该条试卷信息或要求重新输入正确的试卷信息。
题目集三第三题判题程序三
1.答案数量可能不等于试卷题目数量,需要正确处理没有答案的题目、多余的答案以及答案内容为空等情况。同时,要确保答案顺序与试卷题目顺序相对应,并且正确处理题目被删除、答案不存在、引用错误题号等多种复杂情况。例如,如果没有正确处理这些情况,可能会导致判题错误、输出错误提示信息不准确或者程序逻辑混乱。
解决方法:
if (questionOrder <= testPaper.getNumQuestions()) {
answerSheet.addAnswer(answerContent, questionOrder);
} else {
System.out.println("多余答案忽略。");
}
}
}
} else if (answerLine.equals("end")) {
break;
}
在解析答卷信息时,首先获取试卷信息和对应的题目数量。然后,对于每个答案,按照题目顺序进行匹配和处理。如果答案数量多于题目数量,忽略多余的答案并给出提示。如果答案数量少于题目数量,对于没有答案的题目,在AnswerSheet中标记为 “answer is null”。对于题目被删除的情况,在AnswerSheet中标记相应题目为无效,并在输出答案时显示提示信息。在处理删除题目信息时,更新相关题目在questions Map 中的状态,并通知相关试卷和答卷进行相应处理。
题目集三第二题:
1.因为我是用2024年10月14日做的参考星期几,我一开始只考虑了比它早的日期,导致随机到日期大的数星期几的计算方法就不一样了
解决方法:
public int cacuweekday(int year,int month,int day){
if(cacuxiangchaday(year,month,day,2024,10,7)!=-1){
// System.out.println(cacuxiangchaday(year,month,day,2024,10,7));
weekday=7-(cacuxiangchaday(year,month,day,2024,10,7)%7);
if(weekday8)
weekday=1;
return weekday;
}
else {
weekday = ((cacuxiangchaday(2024, 10, 7, year, month, day)) + 1) % 7;
if(weekday0)
weekday=7;
return weekday;
}
}
先对相差天数做判断,如果为负数的话,交换日期位置再一次计算相差天数,并且采用第二种方法计算星期几。
四.改进建议
题目集一第五题判题程序一
1.可以将一些相关的操作封装成独立的方法,提高代码的模块化程度。例如,在Main类中,读取题目信息、处理答题信息等部分可以提取为独立的方法,使main方法更加清晰简洁。同时,对于一些可能会变化的逻辑,如不同格式的输入处理,可以通过封装成方法来方便后续的修改和扩展。
2.在判题过程中,如果题目数量很大,逐个题目进行判断的效率可能较低。可以考虑使用一些更高效的算法,比如并行处理(如果多核处理器支持的话)来加快判题速度。或者对答案进行预处理,例如将用户答案和标准答案进行哈希映射,以便更快地进行比较。(这在后边的判题程序有使用到)
题目集二第四题判题程序二
在计算试卷总分和处理答题结果时,可以避免不必要的重复计算。例如,在Paper类中计算总分时,可以缓存总分值,避免每次需要总分时都重新计算。在evaluateAnswer方法中,对于一些已经计算过的中间结果(如某个题目的得分),可以进行缓存,避免重复计算。
题目集三第三题判题程序三
在查找题目和学生信息时,可以使用更高效的查找算法。如果题目编号或学生 ID 是连续的整数,可以使用二分查找算法来提高查找效率(前提是数据已经按照编号进行排序)。如果数据是无序的,可以考虑使用哈希表来实现快速查找。
题目集三第二题
有专门的库函数计算可以简化函数设计
五.总结
在完成这三次题目集的设计与实现过程中,我学习到了许多关于程序设计、面向对象编程以及输入输出处理的知识。我了解了如何使用合适的数据结构(如Map、List、ArrayList等)来存储和管理不同类型的信息。在处理题目、试卷和答卷信息时,学会了根据具体需求选择最适合的数据结构,以提高程序的效率和可维护性。同时,在处理复杂的逻辑关系时,也锻炼了算法设计和实现的能力。学会了如何处理不同格式的输入信息,并将其转换为程序内部可操作的数据结构。同时,也掌握了如何按照规定的格式输出结果。
在思考问题方面,面对复杂的题目要求时,我学会了仔细分析问题的需求和约束条件,找出关键的问题点和难点。通过对题目要求的深入理解,能够确定程序需要处理的各种信息和操作,以及它们之间的关系和逻辑。
在题目不断增补和修改的过程中,学会了如何应对需求的变化。通过灵活的设计和实现,能够快速适应新的需求和约束条件,对程序进行相应的修改和扩展。同时,也懂得了思考在设计阶段考虑到未来可能的变化,提高程序的可扩展性和可维护性。不然要修改的地方抵得过推倒重来了。