OOP第一次博客作业
前言:
本学期第一次接触java,刚开始对于类的情况搞不明白,加上语法是自学的,所以刚写pta的时候还是有些生疏,加上写C语言的思维方式根深蒂固,所以写java时一些思维并不能很快的转变,在边写作业时边改善自己的思维方式等。与此同时,现在学的不仅仅时java的语法,更重要的是面向对象,这也是老师一直在强调的地方(加上前面根本没有对这方面有过了解,所以刚接触到这些题目的时候还是很生疏的)
前三次的题目集主要考察了我们对java的基本语法,类的一些基本用法,类与类之间的关系以及单一职责原则。前三次题目集一共有12道题,其中每次作业的最后一道题是有难度的,并且是随着每一次作业的进行,都是在前一次作业的基础上加一些功能。对于我来说,我认为每次作业的前面几道题还是比较简单的,但对于每次作业的最后一道题我认为是比较难的,只有第一次作业的最后一题得了满分,后面的两次作业都有大概四五个测试点没过。
在SM中分析出来之后的一些含义:
(1)Lines,代表此文件代码的行数(包括空行);
(2)Statements,代表此文件所拥有的语句数;
(3)%Branches,代表分支语句占语句数目的比例。
这里的“分支语句”指的是使程序不顺序履行的语句,包括if、else、for、while、break、continue、goto、switch、case、default和return。需要注意的是,do不被计算在内,由于其对应的while已计算了。另外,异常处理的catch也被作为1个分支计算;
(4)%Comments,代表注释的比例。
该值是注释行(包括/……/和//……形式的注释)占总行数的比例。
(5)Class Defs,代表类的个数。
包括class,struct和template在内的个数;
(6)Methods/Class,代表平均每一个类的方法数。
即包括内联和非内联的,template函数在内的类方法数除以所有类的个数;
(7)Avg Stmts/Method,代表平均每一个函数包括的语句数目。
由总的方法语句数目除以方法数目得到该值;
(8)Max Complexity,代表最大圈复杂度。
圈复杂度是1个函数可履行路径的数目,以下语句为圈复杂度的值贡献1:if/else/for/while语句,3元运算符语句,if/for/while判断条件中的"&&"或“||”,switch语句,后接break/goto/return/throw/continue语句的case语句,catch/except语句等。对应有最大圈复杂度(Max Complexity)和平均圈复杂度(Avg Complexity);
剩下的看表面意思也知道了其含义。
1.第一次作业:
答题判断程序-1
设计与分析:

首先我创建了包括Main类的一共四个类。其中分别定义了Question类,TestPaper类,AnswerSheet类和Main类。
在Question类中,包括了题目题号,题目内容和题目标准答案,以及相应的getter和setter方法。通过这个类,可以实现对于题目中的题号,题目内容和题目标准答案进行储存。
在TestPaper类中,包括了题目题号以及数量,然后还使用了Question类的对象数组从而进行对相应题号的匹配,以及相应的getter和setter方法。其中题目题号是为了确保每次在答卷上的内容进行匹配,防止出现题号不对应的情况。
在AnswerSheet类中,包括了题目答案以及判断正误的结果,还有定义了判断答案是否正确以及输出内容两个方法。在此方法中定义了两个方法,便于将Question中的标准答案与AnswerSheet中的答案进行比较从而能完成判断。
在Main中,完成了对内容的输入,以及通过正怎表达式对输入的内容中进行分割,将相对应的内容储存到相应的数组当中,最后对相应的内容完成输出。

在这次代码中的Question,TestPaper,AnswerSheet这三个类中的Methods/Class比较大,说明我对于单一职责原则并没有很好的遵守,另外从%Comments来看我并没有很好的注释代码内容,这对于我后面继续完善代码不是很好,这方面我得继续改进。
踩坑心得:
在这次作业当中,报错最多的就是非零返回,而出现非零返回的原因大部分是因为正则表达式没有完全正确。为了解决这个问题,我运用了split和substring方法来进行分割从而解决了问题。

先用split进行分割,将分割的部分存到一个数组中,最后再用substring进行题号,内容,答案等进行存储。
2.第二次作业:
答题判断程序-2
设计与分析:

在这道题目当中我还是创建了包括Main类的一共四个类。其中分别定义了Question类,ExamPaper类,AnswerSheet类和Main类。
在Question类中,还是和第一次作业中一样,包括了题目题号,题目内容和题目标准答案,以及相应的getter和setter方法。通过这个类,可以实现对于题目中的题号,题目内容和题目标准答案进行储存。
在ExamPaper类中,在第一次作业的类中基础上,增加了得到总分的功能以及用了哈希表来确保每次获得的分数与相应的答卷相匹配,另外还有了数组定义了num也是为了进行相应的匹配。
在AnswerSheet类中,在获取答案的方法中采用了ArrayList,其中用ArrayList是为了能够更好的进行答案的匹配。
在Main中,其中还是完成了内容的输入以及运用正则表达式来进行对输入内容的存储,其中还是为了更好的进行匹配,对于AnswerSheet,Question,ExamPaper用了数组的方法。
第二次作业通过这个表来分析,还是和第一次作业的问题差不多,而这次作业中Main中的平均圈复杂度比较大,这对于之后测试与维护不太好,所以我在之后写代码的时候需要注意这方面,另外这次作业中的最大栈深度也相对较大,这会增加内存,在以后这两个方面都需要注意,尽可能的让代码更加精简实用。
除此之外,计算每一张试卷的方法也在Main方法中,以及使用for循环对内容的输出。

踩坑心得:
从这里开始乱序输出,我弄了很久都没有弄出来,而没有过测试点的地方也就是乱序输出的问题。(当时弄了很久都没有弄出来)
在运用哈希表输出时,由于对哈希表不是太熟悉,在输出的时候总分的时候,空格问题没有解决。所以改用了scoreString的方法对总分的输出。
3.第三次作业:
答题判断程序-3
设计与分析:

在这一次作业当中,由于题目变得更加复杂,所以这次多加了两个类。(另外,这次作业当中我基本上都是用的ArrayList来进行存储信息,用此方法可以增加对信息查找的速度并且可以储存null值(这对本道题当中有许多空的答案比较有好处))
在Question类中,在题号,内容和标准答案的基础上,还增加了一个boolean型isCorrect来判断每道题的对错,方便与后面的输出和计算总分。
在ExamPaper类中,运用了ArrayList来存储试卷号,每道题目的对错和相应的分数。
在AnswerSheet类中,也是运用了ArrayList来存储答卷号,每道题目的对错和相应的分数。(因为答案的对错要通过答卷和测试卷上的标准答案进行比较,所以在两个类当中都需要有isCorrect来进行判断)。
在Student类中,包括了学生姓名和学生学号,以及相应的getter和setter方法。
在TestIsCorrect类中,里面要用到以上的四个类,而用了ArrayList来存储questions的信息;里面还包含了checkAnswer方法,也就是这时候要用到ExamPaper和AnswerSheet中的答案;另外在这个类当中还有计算总分的方法totalGrade,在这个方法中还包含了一些内容的输出。
在Main类中,还是内容的输入,以及用正则表达式来对相应内容存储到相应的类中,最后也是有对应的内容的输出。另外,由于此次作业有空的情况,所以对于一些变量需要设置初始值为空,如图所示:

(这里也体现出来了用ArrayList的方便)

第三次作业跟第二次作业一样还是平均圈复杂度和最大栈深度的问题(由于在写代码时并没有注意到这些问题所以在这次作业中并没有得到改善)。
踩坑心得:
首先这次作业中,随着类的增加,使得难度加大了许多。特别体现在运用正则表达式的时候,像我前两次作业中用的split和substring方法在这次作业中就显得不是很好用了,因为此次作业中有许多一个或者多个空格的情况,另外还有空的情况,所以split和substring方法就不太适合了(在弄正则表达式的时候花费了大部分时间);后面用了matcher方法,便很方便的用正则表达式来进行相应的内容存储了。(突然发现在第二次作业时完全可以用ArrayList来写,比哈希表更简单)另外,在写此次作业时我发现出现的比较多的问题便是对于空白卷的相关测试点,在此次作业之后我得注意这方面,并且得思考如何去解决这方面的问题。

如图所示便是用正则表达式对相应内容的存储。(其中最重要的是在进行字符串匹配时中间的空格需要注意,有可能会有多个空格)
改进建议(三次作业的总和):
对于这三次作业,我认为主要不够好的地方便是没有很好的实现单一职责原则,对于用正则表达式对内容进行分割这一块的代码可以新建一个SplitStr类,实现对内容的分割;以及在计算总分时可以新建一个TotalGrade类,而不是在AnswerSheet类中直接对分数进行计算;还有在输出相应内容时,可以新建一个Pirnt类来专门输出内容。增加了这些类之后对于之后的作业继续增加其他的类便可以不破坏原来代码的情况下直接加需要的类,这极大地增加了写代码的效率。并且在此次类设计中我还是没有做好,在之后还得加抽象类方便与后续题目完成继承与多态。
总结
总的来说,经过这三次pta作业的磨练,我对于java已经有了更深的理解,并且对单一职责原则的运用更熟悉了。除此之外,对于类与类之间关系我也能较好的掌握。对于三次作业我收获最大的就是正则表达式的运用,并且我也意识到了正则表达式的重要性,所以在今后学习中我还得对正则表达式进行更加深入的学习。我还感受到了java库数量的庞大,在写很多题目的时候都可以用很多库来写,加快写代码的效率(其中在第三次作业的 日期那道题目,有许多的关于日期的包都可以直接用,相比于C语言简单多了,但对于这些包的运用还是需要多加学习)。另外通过SourceMonitor我了解到了我写的代码还需要注意很多东西,以后工作的时候要注意内存和平均圈复杂度。通过PowerDesigner我可以清楚了解到类与类之间的关系,这对于我之后写类图有很大的帮助。另外,我认为这三次作业还让我受益匪浅的是开始了解到了哈希表和ArrayList各自的优缺点,让我在之后写代码的过程中能够择优选择,而不是仅仅使用数组。但有一点不足的是我对哈希表还不够熟悉,在后面的过程中我还需要对这方面进行系统的学习。
通过这三次作业我感受到了我对于哈希表这方面需要进一步的了解(即使之后可能用不到,但还是要认真学习一下的)。另外,由于我后面两次的最后一题我没有得到满分,我认为主要原因是我对于试卷号,学生的匹配出了问题,在之后我还需要对我的类之间的关系进行进一步的优化。在写代码的时候还需要注意我们的封装性,时刻要注意我们时面向对象程序设计。
浙公网安备 33010602011771号