java三次大作业总结
一、前言:
java近三次题目集类似一个阶梯,难度一节一节上升。
第一次题目集共有九道题,有最基础的数值判断,数值计算;还有部分是判断字符串格式是否正确;以及删除字符串中多余内容——以上这些都是在c中学过相应的语法,并没有太多难题。(但近期学了正则表达式,给身为小白的我带来了在判断字符串格式时候的新奇体验——强!)
第二次题目集共有四道题,在第一次题目集的基础上涉及到了更多内容(真的难了好多,头秃ing),如:①7-1和7-2的菜单计价程序,渗透到了面向对象过程,类和对象的使用等,难点在于:对降低类间耦合性束手无策,仍然带着面向过程思维,对java语法掌握不熟练导致频频报错;②7-3的日期类的基本使用,重点考察到了对Calendar日期类的学习运用,同时也学习到了split等方法,难点在于:面向对象设计做的很难看(对类的设计不够完善,类间耦合性仍然很高);③7-4小明走格子,本题其实做题思路不算太难,但最后一个测试点——运行超时,想必大家都碰见了,我这里用的是字符流输入(BufferedReader)可以大大节省输入所耗的时间,从而很多时候这样可以在算法正当的情况下即便是Java也可以避免运行超时的问题。
第三次题目集共有七道题,考察日期类(Calendar,Date)的使用,对封装性的理解等等。较难题目:①7-4单词统计与理解,涉及到两个排序问题,一个是字符串长度排序,另一个是按字母大小排序;②7-1的菜单计价程序-3,考察了面向对象思维,数组的各种方法是使用,难点在于:首先是判断点菜时间范围的问题,其次是输出问题,再者是运行超时问题。
二、设计与分析:
三道菜单计价程序问题的设计与分析:
1.菜单计价程序-1
1)类图:
2)通过kiviat图找到问题:
(绿色环形区域即被测量维度的期望值,维度上的点则是测量得到的实际值)
由上图可见,该代码的圈复杂度,函数深度等都在合理范围内,也就是说明程序的控制流程复杂度低,易测试与维护。
问题所在:1.平均每个类的方法数(Methods/Class)低于期望值
2.说明各个类中的方法的数量,分布都不均匀,这个问题是源于我对面向对象过程的理解与掌握太少,对类的设计较差。
3)代码度量分析问题原因:
|
菜单计价程序-1 |
%Branches(分支嵌套率) |
18.1 |
Max Depth(最大函数深度) |
4 |
Avg Depth(评价函数深度) |
1.53 |
Max Complexity(最大圈复杂度) |
5 |
Avg Complexity(平均圈复杂度) |
2.33 |
2.菜单计价程序-2
1)类图:
2)通过kiviat图找到问题:
(绿色环形区域即被测量维度的期望值,维度上的点则是测量得到的实际值)
据图分析:
①函数深度和圈复杂度超标
②平均每个类的方法数(Methods/Class)低于期望值
说明三个问题:1.耦合度过高:类与类间分支嵌套过多。
2.圈复杂度过高:也就是各个类的复杂度过高,代码冗长,不清晰明了
3.设计混乱:对各个类中的方法设计混乱
3)代码度量:
|
菜单计价程序-2 |
%Branches(分支嵌套率) |
28.1 |
Max Depth(最大函数深度) |
9+ |
Avg Depth(评价函数深度) |
2.94 |
Max Complexity(最大圈复杂度) |
16(Main.main()) |
Avg Complexity(平均圈复杂度) |
4.12 |
据图分析问题原因:
在最大圈复杂度一栏,我发现主函数main的圈复杂度大于15,也就是说main写的过于复杂了。
结合代码,我在main中写了输入格式的判断(用来区分输入的是菜单还是订单),菜单的查重(似乎这个写到菜单类里比较好(问号脸??),还写了一个判断字符串是否都为数字的方法。这么一想在main里干的事情确实还挺多,似乎把这几个功能瓜分给各个类,圈复杂度会降低不少。
3.菜单计价程序-3
1)类图:
2)通过kiviat图找到问题:
(绿色环形区域即被测量维度的期望值,维度上的点则是测量得到的实际值)
①函数深度和圈复杂度超标
②平均每个类的方法数(Methods/Class)低于期望值
说明三个问题:1.耦合度过高:类与类间分支嵌套过多。
2.圈复杂度过高:也就是各个类的复杂度过高,代码冗长,不清晰明了
3.设计混乱:对各个类中的方法设计混乱
3)代码度量:
|
菜单计价程序-3 |
%Branches(分支嵌套率) |
26.6 |
Max Depth(最大函数深度) |
9+ |
Avg Depth(评价函数深度) |
2.96 |
Max Complexity(最大圈复杂度) |
27(Main.main()=27 Order.discount=16) |
Avg Complexity(平均圈复杂度) |
4.88 |
据图分析问题原因:
①main类和Order类里的discount方法的圈复杂度过高。
main类的复杂度过高的原因是在圈复杂度已经很高(参考上文)的基础上,又增加了新的字符串片段,在while循环里的if又增加一条。
②至于Order类里的discount方法的圈复杂度过高......暂停一下,我来看看代码——好吧,我承认我用了好多好多个if导致复杂度飙升。这是为什么呢?我之前用那个Calendar类里的日期范围判断,不知为何频频出错,而且还运行超时,无奈之下,我只好愤愤的把订单中的时间的字符串转为int型,然后用多个if判断嵌套来判断时间范围,从而算出折扣(菜鸟的无能狂怒)。但其实呢,虽然测试点过了,但是圈复杂度告诉我这并不是一个优秀的代码,所以我还是需要认真研读Calendar类来保证代码质量。
以上,就是大作业中所有关于菜单计价系统的代码,下面来看看其他比较困难的题目。
第二次作业:7-3 jmu-java-日期类的基本使用
1)类图:
2)代码度量:
|
菜单计价程序-2 |
%Branches(分支嵌套率) |
29.3 |
Max Depth(最大函数深度) |
7 |
Avg Depth(评价函数深度) |
2.88 |
Max Complexity(最大圈复杂度) |
15(Main.main(),Judge()) |
Avg Complexity(平均圈复杂度) |
4.75 |
据图分析问题原因:
代码复杂且混乱:branches,complexity过高。
其实在写这题的时候,我没有完全的按面向对象的思维构思,也没有提前画类图,而是写一些想一些,导致各个类写的都很混乱,有判断闰年的类,有计算某日是该年第几天的类,有计算某日是该年第几个星期的类,有判断输入的月份是否合法的类,而其他判断合法输入什么的我又在main里判断,并且在不同的情况中,我犯懒没有直接写一个方法,而是把前面用来判断字符串合法输入的代码复制粘贴,导致代码有不必要的加长,从而导致圈复杂度飙升。
三、踩坑心得
- 运行超时!!
为什么把运行超时放在第一个说呢,当我的代码在eclipse上输入样例全都可以过时, 我两眼放光的把代码再复制到pta中去过测试点——恭喜你得了1分,原因是运行超时(震怒。然鹅虽然“运行超时”这个测试点很让人揪心,但实际上,我也通过这个学会了很多新东西。那么,来看看运行超时教会我什么吧。
①第二次作业7-4小明走格子
通过学习字符流输入(BufferedReader),提升输入速度,从而减小运行时间
②第三次作业7-3去掉重复的数据
在写代码时,最重要的是规划,如果一个for循环就可以解决的问题,不必用更多的for循环而导致运行超时。
③第三次作业7-1菜单计价程序-3
records[],menu[],初始化定义的大小过大(1000多),我猜是因为这个导致运行超时,经过查资料发现,动态数组arraylist可以不用一开始固定数组大小,可以用其add方法增项。用arraylist后就可以过测试点了。
2.非零返回与空指针异常
①java报错空指针异常:如果一个对象本身为空,我们使用对象本身的时候不会出现异常,因为他是有值的,值就是null。可如果我们进一步项直接使用对象内的成员进行操作,按系统就会报空指针异常,因为对象是空的,他不存在成员,那么直接去访问这个车管员,当然会出错。所以在写方法时不要遗漏return null。
②非零返回:我大部分的非零返回原因都是程序的语法在PTA执行的过程中抛出了异常,导致程序没能运行到return,就导致了非零返回。把代码从头到尾看一遍,仔细阅读会发现,在调 用某些类的方法的时候,如果这些方法可能会返回null,应该在调用时判断返回值是否为空,再进行下面的操作,这样说可能不够清晰,下面来看代码示例。
这是在Order类里的删除一条订单信息的方法,这里调用了records[]属性,如果在循环中不加if(records[i]!=null)的判断条件的话,会报非零返回的错,原因是records数组中的项都是通过add方法加进来的,当不满足某个条件时,add方法会返回null,如果满足所有条件,add会返回已经添加到records里的项。也就是说如果在该段删除方法中不加这条判断是否为空的话,如果records[[i]是null,那么在逻辑上是有漏洞的,没法向下进行到return,从而报非零返回的错
四、主要困难以及改进建议:
主要困难:对面向对象的熟练度太低,导致代码圈复杂度,耦合性都很高。
所以应该多用类,分模块来进行,把功能划分给不同的对象,分工合作。
五、总结:
收获:
①学会了数组和String的很多方法,例如split,charat,length,equls等。
②写出了比较有意思的方法,如isNum(判断字符串是否全为数字)。
③学习了动态数组arraylist的使用和其方法(如sort,set get,add等方法)。
④学会了输入流来缩短运行时长。
⑤了解认识了Calendar类和Date类。
仍需改进:
因为有过使用Calendar失败的经历,所以更需要去深刻了解该类的使用去改进代码的不足。
还要就是应该多查些资料看些比较优秀的java代码,从而对自己的面向对象思维进行合理建构。
课业改进意见:
对于后两次作业,比较困难的点其实是我太菜了,要是想把这种对于我来讲比较难的题目在短短一周(还要完成其他课业)的情况下之下做完,实在是太太太太痛苦啦,有一种刚出生就让我说八国语言的压迫感(bushi。改进建议是希望老师不要出题出的难度跨度太大,红豆泥阿里嘎多!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端