目录
一.前言
这两次迭代的大作业难度总体而言比之前要难一点,但收获却很多,话不多说,上知识点。
nchu-software-oop-2024-上-7 ~知识点
- 继承与多态
- 抽象类
- 类的设计
- 正则表达式
nchu-software-oop-2024-上-6 ~知识点
- 继承与多态
- 类的设计
- 抽象类
- 正则表达式
在这两次大作业中,大作业7新添了互斥开关,大作业8新添了二极管。
接下来我会按照设计与分析、采坑心得、改进建议、总结四部分进行这次PTA题目集7~8的总结。
二.设计与分析
对于题目集7~8第一题的分析
一.家居强电电路模拟程序-3
这道题新增了一个互斥开关。
多个并联电路:
对于这个新增内容,对我而言是所有新增内容中最最容易的,早在前一次博客总结中我就说明了自己对电路的设计,虽然那个设计是在第一次电路大作业就考虑好的内容,但思路(在我看来)却足以计算多个并联电路,甚至并中并,并中并中并……只要实现代码不出问题,基本是不用改的。
所以对于这一部分,我几乎就完全没改电路计算的方式,顶多是在判断断路时新添了一个对互斥开关的判断。
互斥开关:
其实一开始对于这道题我是很苦恼的,因为我家电电路大作业迭代2是没有考虑引脚,因为计算电压电流不需要知道各个元器件的具体位置在哪,只需要知道它在哪条线路就行。但是互斥开关有3个引脚,我需要直到它各个引脚对应哪个电路,所以直到这道题我才开始利用正则表达式处理引脚。
在获取引脚前,我对于互斥开关这个类的设计有很多想法,不过基本都不怎么好。
一开始我觉得可以把开关看做是一个“互斥并联电路”,意思就是把它当作并联电路,通过获取引脚来“判定”其中哪条路是断路的,这样做就不会影响我前两次迭代对于电路的计算。
但出于对后续迭代的考虑,我又想,既然它都叫“互斥开关”了,那还是乖乖当个开关比较好。于是我把它拆成了“两个开关”,即一条路线一个普通开关,由互斥开关的状态去决定哪条线路的开关是连通的。最后再利用正则表达式,去连接线路引脚。
虽然当时电路大作业7确实通过了全部测试点,但后面却有很多问题暴露。
二.家居强电电路模拟程序-4
这道题新增了一个二极管,更改了输出内容。
二极管:
这个二极管的设计比较简单,就相当于一个普通开关,通过状态去判定是否通路。利用正则表达式获取引脚,判断是否通电即可。最后题目中对二极管又多了新的说明,根据说明去改就好。
输出内容:
这是我觉得电路四次大作业最最最难倒我的一部分。因为我的计算方式根本不需要考虑具体位置在哪,利用的是“串联电路电路相等,并联电路电压相等”原理,于是也不需要考虑同一条线路上的电压差,毕竟我都知道同一条线路上的电流了,电压差只要通过U=I*R就能计算出来。计算方式的差异使我写电路大作业8时非常非常头疼。
最后采取了什么方法呢,先是重新存储了元器件,按顺序一一存入,然后又给每一条线路一个初始电压,通过U=I * R计算每个元器件的分压。但是想法是美好的,现实是残酷的。想利用U=I * R,那就必须知道I和R,R很好办,这都是已知的,至于I,其实也是已知的,但问题出在哪呢?出在互斥开关上。因为我是把它拆成了两个开关,所以计算分压这方面有了点问题,所以有一些测试点没过。
三.踩坑心得
1.字典序排序
在电路大作业7时有三个测试点非常令我意外,那就是27-29测试点测了排序的问题。
其实这方面的错误是理解错误。题目中说设备是“设备标识+设备编号”,然后同类设备按“编号顺序”从小到大输出。编号顺序是数字,我自然而然就理解为按数字大小排序,但我原本用的是按照字符串大小排序的treemap存储元器件的,于是我特意用了一个方法使它按照数字大小进行输出,却没想到这正是错误的开端。
在前两次大作业中,同类元器件按数字大小进行输出是能通过测试点的,所以大作业7刚遇到这三个没过的测试点时,我从未想过是排序的问题。直到与同学们交流后,才发现这个问题。
2.多个互斥开关
由于一开始互斥开关的设计想得很混乱,所以后续出现了很多问题,导致自己的代码只能应付一个互斥开关的出现,还是后来总有几个测试点过不了才开始考虑多个互斥开关的情况。
关于多个互斥开关,其实就我而言最难的部分是获取引脚,得通过正则表达式获取哪个引脚对应哪个互斥开关,这一部分占了我大部分时间。
其实这一方面如果能做到面向抽象编程的话就不至于这样,每次遇到互斥开关进行同样的操作就可以了。改完之后就通过了这些测试点。
3.连续调速器
连续调速器出了问题,这也是我失误的地方。
电路大作业7写到后期,解决完互斥开关后,竟然还有两个互斥开关的测试点没过,我便一直以为是自己写的互斥开关还不够完善,直到我又去问了同学,才知道这些测试点可能有调速器。
在一番排查后,我发现自己的连续调速器无法工作,输出的电压一直为0。因为新增内容的关系,我改变了自己处理输入信息的主要代码,于是出现了逻辑漏洞,使得连续调速器的档位无法获取到位,于是就一直按照初始档位0来计算。改完后就通过了这两个测试点。
4.排查不周
按道理来讲,改完字典序排序后27测试点就应该过了才是,但它却变成了我最后一个没过的测试点。查了很久很久,自己写了很多很多测试用例后,我终于找到了问题。
在上一次博客总结中我曾提到过除数为零的情况,当时我还说自己已经改完了,结果漏了一个地方没改,其实就是没改全,但是出于“我之前就改完了”的想法,我一直没往除数为0这方面想,还是自己写并测了无数测试点后才发现这个问题。
4.改进建议
1.if-else嵌套
这是我电路大作业7的一个分析图。
这是我电路大作业8的一个分析图。
从图中可以看到,最高复杂度足足有14之高,这个数据不容乐观。
我感觉自己现在写的代码的可读性已经非常差了,处理输入信息的主要函数代码特别的长,各种if else case嵌套。最后一次大作业新添功能时,我看着大段大段写的代码其实是有一种无力感的。这告诉我们,如果不刻意的加以控制,当我们的代码达到了一定的规模之后,某些较为复杂的逻辑就会导致写出很复杂的代码。
再例如,一个函数,有几百、甚至上千行的代码,除此之外各种if else while嵌套,就算是写代码的人,可能过几周忘了上下文再来看这个代码,可能也看不懂了,因为其代码的可读性太差了。虽然我会写注释,但一直下去也不是个办法。
于是我在网上了解到,想避免这种情况可以使用圈复杂度的检测工具,检测提交的代码中的圈复杂度的情况,然后根据圈复杂度检测情况进行重构。把过长过于复杂的代码拆成更小的、职责单一且清晰的函数,或者是用设计模式来解决代码中大量的if else的嵌套逻辑。
这是我一个值得改进的点。
2.其它
- 互斥开关没设计好。
- 输出的分压并不完善
- 代码长且结构越写越乱。
- ……
5.总结
收获:
- 对继承和多态的了解加深。
- 对类的设计的理解加深。
- 单一职责原则。
- 学习了treemap的使用及其部分方法
这两次大作业给我的感受就是应该考虑代码额后续发展,该怎么写更利于后续可能诞生的改变,而不是仅仅是把题目写出来就万事大吉。从读题思考,到类的设计、具体方法、如何实现等,都需要经过很多的考量,如果能独立思考完成这些部分,自己的思维和创造力都会有所提升。
当然,还有一点我觉得必不可少的,那就是同学之间的互相交流。有一些测试点,如果不是旁人多加提醒,或许我到现在还没过。以及蔡老师说的很有道理,大家互测代码确实是一个很好的检验代码的方式,自己平时也可以多测一下代码。
然后,在写题目时,也要多考虑意外情况。虽然电路题大作业并没有错误输入,但是却也有一些需要考虑的点,比如分档调速器的档位问题,它不可能超出自己的档位,也不可能档位为负等等。如果小的细节没有考虑到,最后找错误就会非常麻烦。然后发现错误后进行更改时要仔细,不然就会出现我这样的改完那边忘了那边,最后花半天时间找错误。
最后,本次大作业给我带来了很多提升,同时也让我意识到自己还有很多需要改进的地方。希望在日后的学习中,自己能越来越好。
标签:总结,题目,测试点,开关,代码,引脚,互斥,电路 From: https://www.cnblogs.com/Yemon/p/18275916