JAVA第一次大作业blog
一、前言
在过去的这段时间里,我依次完成了三次题目集的挑战。这三次题目集不仅是对我学习成果的检验,更是我深入理解与运用所学知识的关键途径。
在知识点方面,这三次题目集主要检验对类与类之间的设计与处理。
在题量方面,三次题目集的题量在减少,但难度却在增加。
在难度方面,三次题目集同样呈现出递进式提升的特点。第一次题目内容较少,第二次增加了答卷类,第三次新增学生类,并且更加考验对字符串的处理。
通过这三次题目集的挑战,我不仅巩固了基础知识,还拓宽了知识视野,提高了自己的解题能力和综合素质。接下来,我将对题目集1~3进行详细的分析和总结,分享我的解题思路和心得体会。
二、设计与分析
答题判题程序-1
这是最开始接触的面向对象的程序设计,是对我有关java之前的学习的考验,在解答题目的时候,引入类和对象的概念有助于更好地组织和管理代码,提高代码的可读性和可维护性。
题目内容
点击查看题目内容
设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-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=5true
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,建议增加答题类,类的内容以及类之间的关联自行设计。
PowerDesigner中的类图
这次作业是第一次真正与java有关的作业,题目把类的设计给了我们,但我当时并不懂得对数组的动态操作所以新建一个答案类来记录每一题的答案,用链表来连接,没想到后面居然真的需要写一个答案类。
这是PowerDesigner中的类图。
sourcemonitor中的报表
由此分析:
程序的平均复杂度为4.55,这意味着代码中的方法相对复杂,需要进一步优化。复杂度较高的代码不仅难以维护,还可能影响程序的执行效率。此外,程序的最大深度为60,平均深度为8,而最深的分支深度为9,这提示我们在代码结构方面也有优化的空间。
- 方法复杂度过高:getQuestionContent()方法被识别为最复杂的方法,其复杂度值达到了53。这提示我需要对该方法进行重点关注,以减少其复杂度。
- 代码结构深度:程序的最大深度和平均深度均偏高,可能导致代码逻辑过于嵌套,影响可读性。建议简化代码结构,减少嵌套层级。
- 字符串处理:对字符串的处理比较生疏,进行了许多不必要的操作使代码过于复杂。
答题判题程序-2
这次题目集在第一的题目集上新增了东西,主要是多份试卷和答卷,使得面向对象的程序设计的优势更加好的体现出来,熟练掌握java在未来的编程道路中是非常重要的一步。
题目内容
点击查看题目内容
设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-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,建议增加答题类,类的内容以及类之间的关联自行设计。
PowerDesigner中的类图
这次题目基于之前的题目内容进行了一定程度的增加,主要体现在三种信息的乱序输入了以及多张试卷及答卷和错误提示,按照之前的类,我进行了修改,将之前的链表改为动态数组,考虑到输入顺序打乱,我新建了两个Comparator接口的实现类来排序。
这是PowerDesigner中的类图。
sourcemonitor中的报表
由此分析:
代码的平均复杂度为2.29,虽然不算特别高,这是因为当初学习了ArrayList,对之前所写的代码进行了修改,但仍有优化空间。其中,最复杂的方法为Main.main(),其最大复杂度达到了23。这意味着这个方法内部存在较为复杂的逻辑或嵌套结构,需要重点关注,这是因为我对字符串的处理并未熟练没有使用正则表达式而是直接对字符串进行操作。
- 分支语句的比例为16.8%,意味着代码中大约16.8%的语句是分支语句,分支语句的比例较高可能意味着代码中存在较多的条件逻辑,这可能会增加代码的复杂性,降低其可读性,也可能导致潜在的逻辑错误或性能问题。
- 方法调用比例达到了59%,意味着在代码有大约59%的语句是方法调用语句,过多的方法调用可能导致性能问题或增加代码的复杂性。
- 最复杂的方法的复杂性达到了23,这表明该方法内可能存在较为复杂的逻辑结构,需要进行重点关注和优化。
答题判题程序-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。
本题暂不考虑出现多张答卷的信息的情况。
PowerDesigner中的类图
这一次的题目集新增了一个有关学生的信息,对错误的提示也增加了许多,难度提升了很多,对字符串的操作要求也更加高了,对此我新增了一个学生类来进行操作,考虑到判断条件添加,所以我对之前的类进行了些修改,在对字符串的操作中用了少量正则表达式,但因为并未熟练掌握而导致代码复杂。
这是PowerDesigner中的类图。
sourcemonitor中的报表
该文件的分支语句比例为21.2%,意味着代码中存在一定数量的条件分支逻辑,需要关注以确保逻辑的正确性和可维护性。同时,方法调用次数达到了100次,显示出方法的频繁使用,需要注意性能优化和代码复用,平均复杂度为3.44。这些类的复杂度水平适中,但仍有优化空间。
- 平均复杂度为3.44可能表明代码的整体复杂度适中,但并不意味着没有优化空间。
- 过高的方法调用次数可能带来一些潜在的问题。它可能增加程序的执行时间,因为每次方法调用都需要一定的计算资源。同时,过多的方法调用也可能导致代码难以维护和理解。
- 该文件的分支语句比例为21.2%意味着在代码这个文件中,大约每五个语句中就有一个是分支语句,这是对字符串的处理过于复杂。
三、踩坑心得
1、答题判题程序-1
第一次题目集难度较低,测试也比较松散,也给了类的设计建议,所以并没有遇到太大的问题,做起来还是比较顺利。
2、答题判题程序-2
第二次题目集只是在第一次题目集上稍作修改,但我仍是有写细节没有注意而导致踩坑。
-
之前判断是否试卷为一百分以为是判断是否低于一百,而没有考虑高于一百分的情况。将
if(listPaper.get(i).getSum()<100)
改为
if(listPaper.get(i).getSum()!=100)
就通过了测试点。 -
没有注意对输出顺序的要求,但出现多份答卷和多份试卷的情况下,对输出的结果会出现顺序错误,新增两个Comparator接口的实现类来排序。
class AnswerPaperComparable implements java.util.Comparator{
public int compare(AnswerPaper x,AnswerPaper p)
{
return x.getNum()-p.getNum();
}
}
class PaperComparable implements java.util.Comparator{
public int compare(Paper x,Paper p)
{
return x.getNum()-p.getNum();
}
}
再在输出前对试卷和答卷进行排序
Collections.sort(listPaper,new PaperComparable());
Collections.sort(listAnswerPaper,new AnswerPaperComparable());
就可以解决输出顺序的问题。
3、答题判题程序-3
第三次题目集新增了一个学生类,对字符串的操作要求也更加大,所以在第三次题目集中我踩了许多坑,遇到了很多问题。
-
输入空的答案,我的代码并没有进行相关处理,而是简单的对字符串进行分割后传入构造方法中从而导致出现错误。新增一个判断条件
if(strs3.length==1)//如果答案为空时
Answer answer=new Answer(answernum,"");
else
Answer answer=new Answer(answernum,strs3[1]);
则就可以解决空答案的问题。 -
答案的输入顺序的可以是打乱的,由于开始是从题目集二改的所以并没有注意这种情况,将题目和答案的获取新增一个判断条件
if(x.getNum()==i+1)//i+1为试卷中的题目序号,x为答案
就可以解决这个问题。
四、改进建议
针对以上问题和心得,我思考出以下改进建议:
- 加强基础知识的学习和应用。只有掌握了扎实的基础知识,才能更好地应对各种复杂的题目和挑战,在学习过程中,将重要的知识点、公式或理论记录下来,有助于加深自己的记忆和理解。
- 对字符串的处理,尽量避免使用复杂的正则表达式,因为它们可能导致处理速度变慢。尝试将复杂的正则表达式分解为多个简单的表达式,并分步骤处理。使用具体的字符集而不是.来匹配任意字符,特别是在你知道输入字符串的特定格式或范围时。这样可以减少正则表达式的匹配范围,提高准确性。
- 对代码的逻辑进行更深一步的思考,在编写代码时,逻辑清晰和高效至关重要。复杂的嵌套结构会使代码难以理解和维护。尝试通过提取方法或重构逻辑来简化嵌套结构。可以改进代码的逻辑结构,提高代码质量和可维护性。检查代码中的逻辑分支是否有冗余或重复的情况,通过合并条件或使用状态机等方式来减少分支数量。
- 增加注释:在编写代码的时候我基本上没有加上注释,当我们在代码中添加了注释后,即使长时间没有再次查看这段代码,我们也可以通过注释迅速回忆起当初的设计思路,从而避免因为遗忘而重新花费大量时间去理解代码,从而提高代码的可读性和维护性。
五、总结
通过题目集1~3的学习和实践,我深刻感受到了编程的魅力和挑战。我不仅掌握了更多的编程知识和技能,还学会了如何分析和解决问题。同时,我也认识到了自己在编程方面的不足和需要进一步提高的地方。在第一次的题目集中我因为还未掌握ArrayList的操作而使用链表导致代码的复杂程度增加,后面通过学习,对自己的代码进行优化,在对输入信息的处理中,我并没有对正则表达式掌握透彻,而导致三次题目集都没有进行较好的处理,甚至在第三次题目集的测试中出现了许多错误,在接下来的学习中我会加强自己对字符串的处理和对正则表达式的学习,在未来的学习中,我将继续努力提高自己的编程能力,不断探索新的技术和方法。同时,我也会积极参与课程的学习和讨论,与同学们共同进步。对于课程方面,我认为可以进一步增加实践环节的比例,让我们有更多的机会去动手编写代码和解决实际问题。此外,还可以加强与其他课程的联系和整合,形成更加完整和系统的知识体系。在未来的编程实践中,我计划更加细致地梳理类之间的关系,以期提高代码的整体健壮性和可维护性。通过完成这三次作业,我深感收获良多。它们不仅加深了我对Java编程的深入理解,还让我清晰地认识到自己在面向对象设计方面尚存的不足。我深知学习是一个持续的过程,因此我将保持谦逊和进取的态度,继续磨砺自己的编程技能,提升面向对象设计的能力,力求在编程的道路上不断前行,取得更大的进步。