一、前言
书接上回,家居强电电路模拟程序。堆砌代码是由好处的,在我扩展程序的时候只需要复制粘贴,改一改关键词,多出一大段重复代码,新的设备就能完美的添加到程序当中,耗时短(指我自己改代码),效率高(添加一个设备仅需10分钟),牺牲了代码的效率,整体的简洁度,虽然后来想到了更好的处理方式,但奈何代码已经成山,动一下都是删了重写的程度,实在是不肯用多余的精力处理一个能跑的代码,于是在第八次大作业吃了亏,被史山拖住了腿,完全没有办法构造新思路,最终又堆了两次代码,成功运行所有样例,然后就是代码长度超限,当时长度还没有放开,我于是又进行一些优化,把代码量降低到70.4kb,然后成功的失败了,样例都没过几个,最后只剩下一天时间,无可奈何的放弃了,毕竟还有其它科目要去复习。下学期再也不堆史山了。
简单说一下第七次题目集,除了刚开始的窗帘事故(默认全开)和排序事故(设备并非按照数字大小顺序,而是根据ASCII码表的字典排序)以外,总体上还是能做的,毕竟只是单纯的加了个设备,串联套串联,多了个电阻而已!由于我的垃圾设计没用递归算电阻,以防信息输入顺序错乱,选择了拆解电路的做法,事实证明白扯,第八次大作业直接打回原形。
至于第八次题目集,已老实,求放过。更改了输出信息,要求输出引脚信息,由于我的代码设计,他不连通的线路,是没电压的啊!现在还要求供上电压,直到断点前都是有电压的,有点为难人,好在短路还是很好搞的,判断总线路是否连通,如果连通线路电阻是否为0,如果为0则短路,勉强拿了几分。
二、大作业分析
第七次大作业分析
第七次大作业还好,至少不是没思路。
本次新增了一个风扇,没什么好说的。重点在于串联套串联,电阻是递归算法的有福啦!直接套一层递归就结束啦!不像我这种干路算电阻的,想了半天想了个仿递归的,当线路设备中匹配到T,寻找T,将T中设备加入到线路,删除T,循环-1。
虽然不太好,但能用就行,仅需要四层循环,就可以完美解决电阻问题。
需要注意的是此次29,30,31测试点,在于开关K设备排序并非是按照数字大小排序,比如正常序号1,3,21排序,但是实际上是字符串的排序1,21,3这样的,大部分卡在91分的同学可能是这里出了问题。
其他同学也可能出在同一线路双互斥开关这里
比如T1:[IN H1-1] [H1-2 H2-1] [H2-3 OUT]
这种情况可能某些同学没有考虑,只检测了一个互斥开关,导致错误判断该线路连通,最终结果出错。
SourceMointor报表如下
第八次大作业分析
无论怎样,这最后一次作业终究是没能完成。
先说一下能过样例的思路吧,首先对所有线路连通性检查,连通check=1;因为不闭合的线路不会添加到链表中,所以这部分线路没有电压,现在第一步是检测干路中的并联线路,将已经分配给并联线路的电压赋给所有并联线路中的线路,之后再次寻找改并联线路中的线路,是否存在并联线路,如果存在,检测当前线路连通性,看是否有开关挡在了并联线路之前,如果没有就把电压传递过去。
互斥开关需要进行一个判断,引脚是2,3在前还是1在前,由于我用空格将线路信息进行分割,所以设备引脚靠前的一定是 H1-X] 包含“]”,通过正则表达式匹配即可,之后判断开关状态,传递电压。
当电压传递完毕后,将所有check==0的线路电压归零,防止后续计算电流出错。
最后梳理一下这次做题的思路吧。
首先,由于最开始将所有设备存入容器出错,所以改为所有设备都是单独一个链表,每次增加设备都是新增一个链表。
首先我将每一行信息都存入到一个String类型的链表中,直到end为止。
其次,录入串联信息,首先将一行信息,根据空格切割,其次根据
.*([A-Z])(\\d+)-(\\d+|IN).*
来匹配设备,这样设计主要是刚开始不需要考虑多引脚,只需要存入设备序号即可,后来多了个互斥开关,必须要存引脚信息了,才不得已改掉正则表达式。
其它设备正常存入设备类型+序号的字符串,互斥开关特殊存入引脚2,3。
互斥开关存入两次,作为两个普通开关使用。
这样存会导致设备重复存入,K1-1 K1-2都会匹配,并存入K1,所以用hashset去掉重复元素。
如果互斥开关并不是在并联线路中,那么一般只会存入一个互斥开关H1-3,这会导致缺少H1-2的信息,最后输出引脚信息时会出错,所以我们需要加一个处理补全H1-2
这里就是检测H链表中序号相同的是否出现2次,如果少于2次,则代表该开关需要补充引脚。
之后就是解决互斥开关状态了。
接下来是存入各种设备,同时还有普通开关的状态也需要切换,分档调节器也需要切换等等。
解构设备T,如果一条线路的设备链表中含有T,则需要找到该线路T,并将该线路的所有设备加入到被解构的线路中的设备链表,同时该链表中的T设备被删除,循环减去一层。
基础数据处理完毕后,就是要创建并联线路了。
匹配信息找到M,匹配其中的线路,检测线路是否闭合,如果闭合就将T加入到该并联线路的设备链表中。
线路整理完毕,开始计算所有T的电阻,T算完后计算M的电阻。
电阻计算完毕后进行线路干路的连通性检查。
如果连通,开始给干路分压,先考虑变压器,再根据电阻之比等于电压之比分压。
干路分压完成再考虑并联线路分压。
最终输出信息。
以上就是大作业的基本思路。
三、踩坑心得
无论强调多少次,设计依然是最重要的,一个好的设计会决定最终走向,比如如果是递归计算电阻,我就不必在处理嵌套线路的电阻上痛苦。
当你觉得一个设计足够合理,但是却没有能力实现时,一定要想办法克服,如果这次设备存入的是一个容器链表,我就没必要每个设备都创建一个链表,导致代码量过大。
当你觉得处理一些东西感到麻烦,不妨上网查一查,比如去除重复元素,ArraList可能很难做到,但转换一次hashset就可以解决。没必要用C语言的思路来处理Java,Java的工具包还是很强大的。
四、改进建议
建议是推翻重写,选用更优质的方法完成设计。多与身边同学讨论,一个好的思路绝不是闭门造车就可以造出来的,巧妙运用算法和工具包等,基本信息处理要做好,比如LinkedHashMap这种特殊链表,要是我早知道,我早就改用这个了,比ArrayList更加适合信息处理。
设计的时候我的建议是,尽量不要考虑老师会出多少层嵌套和循环,比如这几次大作业,最多也就三层,甚至可能没有三层,但我们如果自己要用的话绝对不止三层,一个好的设计是会适配各种环境的,而不是单纯的应付了事。
五、总结
这几次大作业下来,我是真老实了,读不懂的题目,想不出的设计,运算的处理,等等等等,哪怕前三次都是满分,第四次也是直接让我摔死在地上,永远也想不到到底会是怎样的折磨。说点不客气的,我觉得第四次完全是为了难而难的题目,虽然一开始就让我们考虑引脚,但前三次大作业完全不管引脚如何如何,题目也是一点也不在乎,到了第四次突然改变了整个输出方式,考虑引脚这么大的处理,偏偏代码已经变成了不考虑引脚的样子,已经成型了,再改也不是很好改了。
我认为大作业最痛苦的便是更改输出信息,每个人的代码设计是不同的,数据处理也是多种多样的,比如我们都是电阻分压,而有的人却是根据电流来分压,电流那种需要明确精度值的东西,所处理的数据肯定会与电阻分压的数据有些细微的差别,比如第一版的大作业题面,同一个电压灯泡却有着不同的lux,偏偏lux是根据电压计算的,所以肯定是电流和电阻计算出的电压与电阻分压的不同导致这一丝丝的差距,最终结果出错。而更改了输出信息,更是让这种细微差别出错的概论放大。更改输出信息,我当时是真的没办法了,甚至打算放弃电阻分压,将代码重写改为电流算电压。
倘若前几次大作业中输出信息中包含引脚信息,那么我们一开始的设计就会考虑引脚这种信息的处理,这最后一次大作业也不会如此的狼狈,哪怕最开始就提示了引脚这种东西,因为他对题目得分不重要,所以我们便不考虑,最终重重的摔在了地上。
总结就是,接下来我会将各种情况考虑在内的,不会因为对得分不重要就不管不顾,但也请求老师,出题连贯一些,哪怕是第三次开始考虑引脚信息输出呢?第三次大作业代码基本成型,我实在是无力考虑引脚信息了。
拜谢。