(1)前言:
这几次的大作业的包含了String类的使用和各种String的处理方法,包括字符串按照正则表达式查找和切割。
以及很多新知识点,包括类的封装,继承和多态,其中继承可以说是贯穿整个程序,继承可以让程序简单易读,好修改,
而这个还要求进行一个复杂性很高的排序,所以还用到了TreeMap集合进行管理和储存,利用里面的key值还自定义的排序规则进行排序,
这三次作业的题量没有很多也没有很少,只能算是中等。
难度也没有很难,因为对于我来说只要不是题目看不懂,或是要求不清晰,花花时间都能给他搞出来,但是写代码的时候确实要仔细仔细再仔细,不然会出现一个小错误导致卡你半天。
这一个相对于上一次的大作业而言,我觉得最大的改进在于main方法的改进,有了上一次的经验,我将main方法里面的代码都进行的方法的包装,每一段步骤都包装成一个方法,这样什么地方需要改进,我就立马知道
要去哪里改。这样真的节约的很多找代码的时间。
(2)设计与分析:
首先是第一次的大作业的第四次迭代,相比于第三次迭代,它新加了多选题,和多选题的判分方式以及填空题和填空题的判分方式,还有题目的乱序输入以及多张试卷的情况。
先看看整体的类图,与上一次相比,多了一个选择题和填空题,以及里面的判题方法,其他的地方并没有太大地方的改动,输入和输出方式也和上一次没有什么太大的区别,这里就不赘述了。
第二次大作业第一次迭代的题目,看上去很复杂,但给出的样例确是异常都单一,几乎就只有一个调节器或一个开关加上一个用电器的情况,而且位置也几乎不变,所以要写写对第一次迭代的题目并不难,甚至如果不管下一次迭代的话,都可以用暴力破解的方法去写,因为情况就那么几种,只要都考虑到了几乎就可以拿满分了。
但我们需要考虑的不仅仅是一次迭代而已,首先我们要建立一个共同的父类,电器类,电器类下有控制设备类和受控设备类去继承它,以上的三个类最好设置为抽象类,而其他的像开关,分档调速器,连续调速器就继承控制设备类;白炽灯,日光灯,吊扇就继承受控设备类。
以上是这次大作业的类图
想好了类与类之间的关系之后,我们就要抽取相同的属性到父类里面,首先关于电器里面的两个引脚是所以设备的公共属性,所以应该定义再电器类里面,还有名字也是公共的属性,也应该定义的电器类里面。各种控制设备有自己的状态,所以控制设备类里面应该定义一个状态属性。
以上这些是通用的部分,接下来的东西是我对这个题目分析的自己的想法:
首先将定义一个打印信息的方法在电器类里面,用与打印出每一个电器自己的信息,但由于每一个电器的呈现方式和信息是不同的,所以我将这个方法设置为抽象方法。
我将这些电器以一种像是链表的方式连接起来,在用递归的方式来判断这条路是否是通路或是短路,或是断路。
这时就要定义一个next属性在电器类里面,类型是电器类,默认是null。
确定好思想后我就要加两个方法,一个是run方法,一个是isRun方法,isRun方法用来判断电路是否为通路,或者短路,或者断路,返回类型为boolean类型,通路和短路返回的都是true类型,而断路返回false类型
run方法用来启动电路,从头开始,一直到末尾结束,中间进行改变受控设备两端电压的操作。
(run方法和isRun方法由于不同的设备同样会有所不同,所以同样声明为抽象方法)
而控制设备也有他们独有的属性和方法,属性为state,方法为control,属性用来表示控制设备当前的状态,control方法用来改变当前的状态
由于每一个控制设备改变状态时的操作并不一样,所以我将control方法声明为抽象方法,要求子类去重写它。
最后就是打印设备信息的操作。
这些是我的大概的思路了
而对于第一次的迭代来说,这些已经足够用了,但是第二次迭代来说却还有点不够的,第二次迭代新加了落地扇,还新加了串联电路的输入和并联电路的输入,我还为白炽灯和日光灯增加了一个父类
灯类,并抽取他们之间的公共的方法到父类里面。
对于串联电路和并联电路,我在写第一次迭代的时候就已经想要建立一个串联电路类,和一个并联电路类,第二次迭代也是验证了我的思路,一看到题目我就迅速建立了一个串联电路类,和一个并联电路类
并让他们继承最大的电器类,方便后面用多态进行使用,并且我为这两个类定义了一个额外的属性,电器类的集合,在串联电路里,集合里的元素被当作是串联电路的各个电器,而并联电路里集合的元素就被当作是许多电器或电路并联起来。
解决了串并联的问题,就要解决他们之间的方法了,他们都需要重写电器类里面的抽象方法,而由于各种设备以及重写过这些方法了,串并联电路严格来说并不算是电器,所以他们重写方法时只需要调用集合里面元素的方法就行了
因为第二次的迭代对输出的的顺序有要求(其实第一次也有,只不过第一次的样例较少,可以耍点小聪明混过去)
所以我定义了一个TreeMap集合来存储所有的设备信息,但这时会有一个问题,排序方式该怎么办?
我们可以看到对于这些设备来说,它的设备信息并不能用来当作它排序的凭据,它并不是一个从小到大的顺序,得用其他的信息,那么该怎么办呢?
我当时想到了一个方法,
我为什么不自己给他们的类标一个号,比如说从开关到落地扇,对应的编号从1到7,在加上他们的序号,组成一个字符串当作TreeMap的key值,而排序的方法如下:
先比较编号,如果相同再比序号,这样一来就节约了很多比较的时间。
另外第二次迭代还加上了电阻,看上去很复杂,其实也就是加了一个分压的方法,所以整个程序其实只需要再计算电压的时候进行微调就好了。
当所有的信息输入完成后,相应的电压计算完毕,就可以直接遍历TreeMap集合并调用里面每一个元素的打印信息的方法就好了。
(3)踩坑心得:
这几次迭代还没有出现让我爬不起来的坑,但也还是有一些小坑再里面,
首先是代码再一开始写的时候并没有考虑到短路的情况,这导致游戏并联的测试样例一直过不了,不过这还是小事,有两个不知道算不算是坑的地方着实恶心到我了。
其中一个是计算并联电路电阻的时候,不知道当时的脑子怎么回事,我直接把计算有两条线路的并联的方法用到了所有线路上。。。
这是改进前的代码
改进后的代码是只样的:
完全没有一点关系,也是幸亏这次的测试样例中没有两条线路以上的测试样例,不然我直接g
另外一个坑是再一个很关键的位置少写了一段很重要的代码(明明记得我写了,但是就是没有)
真的卡了我好久好久。。。
所以下次写代码的时候一定要仔细仔细再仔细。
(4)改进建议
代码改进的话其实可以改进很多东西,其中较为重要的一定就是,避免代码的冗余,相同的代码写了太多次了,其实可以都抽调成一个方法,这样可以节省很多的空间。
而且注释一定要写,我个人认为注释还是挺有用的,我其实也写了一点
但到了后面敲代码的时候不是忘记写,就是觉得下一次我看这些代码的时候肯定可以记起来,结果可想而知,我真是太高看自己,上个厕所回来都可能会忘记写到哪了,我居然觉得我可以记得上一次写的什么东西,
总而言之,写注释,不吃亏。
(5)总结
经过了这几次的作业,让我学到了如何更好的包装一个类,以及类雨类之间的继承关系,多态的多种使用方法和使用场景,还学到了很多String类自带的方法,包括trim,split,matches等等,以及正则表达式的应用,还有TreeMap,ArrayList等集合以及可以熟练的使用了,lamda表达式也能熟练掌握了,还有课外方面的,比如API文档的使用。
但是还有很多不足的地方,类与类之间的关系应该设计的更加的合理,数据结构感觉还有可以改进的地方,对于错误以及报错分析的不够完美。
这一次相比于上一次的大作业难度相差不大,甚至因为测试点都比较简单,题目难度就更下降了一个档次,
不过题目还算比较新颖,让我找到了新的程序设计方式。