第三次blog
一.前言
7-8次大作业对前几次的大作业的设计进行了进一步的迭代,第七次大作业加入了并联串并联和串联套串联的情况,并且加入了相对比较麻烦的互斥开关,和一个受光窗帘;但是第八次大作业却是真正的大boss,我写了将近四个多小时才写到36分,前面有几次三小时就可以满分了,并且因为最近到了考试周了而我很多科目说实话并没有太大的把握所有我多花了一些时间给其他的科目和一些其他的原因导致的对这次大作业写的不愿意导致第八次大作业我给的时间没有很多也导致了分不是很高。对于题量来说吧第七次和第八次简直不是一个量级的,第七次花了我差不多三小时就接近满分了(最后三分的错误写第八次大作业的时候才发现,是没有考虑窗帘在支路的情况),而第八次大作业四小时才拿到36分,还有很多考虑的地方还没写进去,就已经写了将近1500行了。难度也是第八次大作业最难.难写。
二,大作业与代码分析
1,第七次大作业
第七次大作业相较于第六次大作业加入了互斥开关,窗帘,串联套串联的情况,总体较麻烦的是互斥开关,为了处理这个我将互斥开关看做是两个独立但是同时只能存在一个打开的开关去处理,下面列举一些相关代码
class Huchi extends Controler{ private int rank=0; private double R2=5; private double R3=10; private ArrayList<KaiGuan> kg=new ArrayList<>(); public Huchi(String name) { super(name); kg.add(new KaiGuan("er")); kg.add(new KaiGuan("san")); kg.get(0).changeCondition(); kg.get(0).setR(5); kg.get(1).setR(10); } public void changeCondition(){ kg.get(0).changeCondition(); kg.get(1).changeCondition(); } public ArrayList<KaiGuan> getKg() { return kg; } public double getR2(){ return R2; } public double getR3(){ return R3; } public int getRank() { return rank; } }
这是我设计的互斥开关类,其中包含了两个开关与他们自带的阻值,其中的rank是后面用于排序的,我前面也谈到过,我在里面还设计了一些方法比如互斥开关的改变等以处理互斥开关相关的事宜。
else if(c[0].startsWith("H")){ if(c[1].equals("1")) { x = e[j + 1].split(" ")[0].split("-"); boolean h = false; Huchi H = new Huchi(c[0]); for (int k = 0; k < QIKU.size(); k++) { if (QIKU.get(k).getName().equals(c[0])) { H = (Huchi) QIKU.get(k); h = true; break; } } if (h == false) { QIKU.add(H); } ArrayList<KaiGuan> kg = H.getKg(); if (x[1].equals("2")) { line.add(kg.get(0)); } else if (x[1].equals("3")) { line.add(kg.get(1)); } }else{ boolean h = false; Huchi H = new Huchi(c[0]); for (int k = 0; k < QIKU.size(); k++) { if (QIKU.get(k).getName().equals(c[0])) { H = (Huchi) QIKU.get(k); h = true; break; } } if (h == false) { QIKU.add(H); } ArrayList<KaiGuan> kg = H.getKg(); if (c[1].equals("2")) { line.add(kg.get(0)); } else if (c[1].equals("3")) { line.add(kg.get(1)); } } } }
考虑到互斥开关具有很强的可变性列如可以正接也可以反接,可以将二节点放在上面也可以将二节点放在下面所以对于它的输入我单独考虑了很多东西也导致它的输入代码挺长,主要思路就是先判断它是正接还是反接,然后判断接的是二节点还是三节点,再进行相关的处理。
class SkChuanglian extends Equipment{ private int rank=-1; private double R=15; private double sumlux=0; private double openrate=100; public SkChuanglian(String name) { super(name); } public double getR(){ return R; } public int getRank() { return rank; } public void getNowOpenrate(ArrayList<Facility> ku) { for (int i = 0; i < ku.size(); i++) { if(ku.get(i) instanceof BaiChi){ sumlux=sumlux+((BaiChi)ku.get(i)).getBrightness(); }else if(ku.get(i) instanceof RiGuang){ sumlux=sumlux+((RiGuang)ku.get(i)).getBrightness(); } } if(sumlux>=0&&sumlux<50){ openrate=100; }else if(sumlux>=50&&sumlux<100){ openrate=80; }else if(sumlux>=100&&sumlux<200){ openrate=60; }else if(sumlux>=200&&sumlux<300){ openrate=40; }else if(sumlux>=300&&sumlux<400){ openrate=20; }else { openrate=0; } } public double getOpenrate() { return openrate; } }
还有就是受控窗帘,受控窗帘这个点并不是非常的难,他的处理应该放在所有用电器处理完之后,或者放在所有灯类用电器处理完之后。上面是我对受控窗帘类的设计,没有什么特殊的
for (int i = 0; i < QIKU.size(); i++) { if(QIKU.get(i) instanceof SkChuanglian){ SkChuanglian a=(SkChuanglian) QIKU.get(i); a.getNowOpenrate(QIKU); } }
这是在所有用电器处理完之后对于受控窗帘的处理,起算它的开合程度
而对于串联套串联,直接把串联当做一个用电器连在电路里就好了,再对于这个串联原件设计一个递归方法来处理相关问题,这里就不进行代码演示了
总的来说这次大作业的难度中等,比较容易犯错的地方就是互斥开关的反接和串联套串联的情况,还有就是受控窗帘的处理一定要放到最后来进行处理,这次写的时候也忘了窗帘还可以放在支路里所以进行支路输入的时候没有判断窗帘的情况导致这次没有满分,以后思维要更加严谨一点
下面放一下类图
可以看出类还是比较多的
以及类的复杂度,可以看出对于其他类复杂度是比较合适的2,而对于工具类因为其担任了对于电路的各种操作,所以其的复杂度也是超了挺多的,也可以看出tool类也是可以进行一定的优化的。
2,第八次大作业
说实话第八次大作业的难度应该相比较于前几次大作业应该是断崖式的增长,从最后的排名也可以看得出来,排名第一的孩子也没有斩获满分的好成绩,侧面也是反应了这次大作业的无比棘手,从我对于周围人的了解来说这次大作业也耗费了他们很多的时间。
这次大作业相较于前一次加入的东西就比较多了,包括什么二极管,引脚电压,还有什么过载情况,相应的,对于这次的代码改进也会相应多很多,这次加入了一些相当麻烦的东西,比如引脚电压的输出,引脚电压的获取是相对于比较麻烦的,并且前几次对于用电器的处理用分压就好了根本用不上引脚导致很多人都没有进行相关的处理,而这次的加入显然就要在代码里加点东西了,并且有一些比较恶心的点就是对于断了的电路居然还能有电压传递,这是令我感觉到比较抽象的,没有回路的存在还能传递电压有点违反我高中学的物理常识,所以我开始写的时候并没有考虑这点,还是看样例的时候才发现的。
对于二极管来说一开始我的确给他单独的创建了一个类去处理它,但是我写着写着发现好像这个二极管完全符合开关的一切属性,正着代表着开关的闭合,反着接就代表着开关的打开,而且这个玩意儿的打开关闭是不会变的,所以严格意义上来说它更加易于处理,于是我就使用开关类来进行处理了,只是在输出的时候根据名字来判断是输出开关的结果还是输出二极管的结果
f (QIKU.get(i) instanceof KaiGuan) { KaiGuan a = (KaiGuan) QIKU.get(i); if (a.getName().startsWith("K")) { if(a.getelI()>=a.getI()) { if (a.getCondition() == 0) { result.add("@" + a.getName() + ":turned on" + " " + (int)a.getBegin() + "-" + (int)a.getEnd()); } else { result.add("@" + a.getName() + ":closed" + " " + (int)a.getBegin() + "-" + (int)a.getEnd()); } }else{ if (a.getCondition() == 0) { result.add("@" + a.getName() + ":turned on" + " " + (int)a.getBegin() + "-" + (int)a.getEnd()+guozai); } else { result.add("@" + a.getName() + ":closed" + " " + (int)a.getBegin() + "-" + (int)a.getEnd()+guozai); } } } else { if(a.getI()<=a.getlI()) { if (a.getCondition() == 0) { result.add("@" + a.getName() + ":cutoff" + " " + (int)a.getBegin() + "-" + (int)a.getEnd()); } else { result.add("@" + a.getName() + ":conduction" + " " + (int)a.getBegin() + "-" + (int)a.getEnd()); } }else{ if (a.getCondition() == 0) { result.add("@" + a.getName() + ":cutoff" + " " + (int)a.getBegin() + "-" + (int)a.getEnd()+guozai); } else { result.add("@" + a.getName() + ":conduction" + " " + (int)a.getBegin() + "-" + (int)a.getEnd()+guozai); } } } }
因为这次输出加入了过载的情况,而开关和二极管又都有两种输出情况,所以达到了整整八种情况,所以看起来还是比较多的,还有就是引脚的处理,引脚的处理得分情况来处理,在一般电路里的处理还是比较好写的,在之前的元器件处理方法代码里加上对于上一个用电器的尾引脚的电压索取和根据自己分压来给自己的尾引脚来赋值电压,麻烦的一个是在已断电路的引脚电压赋值,另一个就是对于反接元器件的处理,因为我对于用电器的处理开始是没有考虑反接情况的,导致反接后输出的两个引脚的电压是反着的。
先来聊聊第一种情况,断路的引脚电压赋值,先给大家看一看我这部分的代码
else{ for (int i = 1; i < rline.size() - 1; i++) { if (rline.get(i) instanceof FenDuanControler) { continue; } else if (rline.get(i) instanceof LianXuControler) { continue; } else if(rline.get(i) instanceof KaiGuan){ KaiGuan a=(KaiGuan) rline.get(i); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin() - zv * (a.getR() / zR)); }else if(rline.get(i) instanceof SkChuanglian){ SkChuanglian a=(SkChuanglian) rline.get(i); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin()); }else if (rline.get(i) instanceof BaiChi) { BaiChi a = (BaiChi) rline.get(i); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin()); } else if (rline.get(i) instanceof RiGuang) { RiGuang a = (RiGuang) rline.get(i); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin()); } else if (rline.get(i) instanceof DiaoFan) { DiaoFan a = (DiaoFan) rline.get(i); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin()); } else if (rline.get(i) instanceof LuoDiFan) { LuoDiFan a = (LuoDiFan) rline.get(i); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin()); } else if (rline.get(i) instanceof BingLine) { BingLine a = (BingLine) rline.get(i); setBing(a, zv * (a.getR() / zR)); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin()); } else if (rline.get(i) instanceof ChuanLine) { ChuanLine a = (ChuanLine) rline.get(i); setChuan(a, zv * (a.getR() / zR)); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin()); } }
大家也可以看到前面有个“else”这是因为前面的if是用来判断这个电路是否“死亡”,我会给每个开关断开的电路附加“死亡”的属性,所以加个else,而为了给这里的引脚赋值我对于用电器处理的方法长度几乎翻了一倍,导致我写的十分难受,因为我想写一些新的东西,而不是复制我的代码为了达到目的使其变得更加复杂(也可能是我没有想到更好的方法),也是写到这使我对于这次大作业的写的欲望消减了很多,还有就是如果是并联里的支路出现这种情况也很难受,因为需要先给第一个用电器赋值再进行后面的引脚赋值。
其次就是反接。
反接对于我的代码我并没有加进去,因为我那是还有点其他事导致时间不够多了,而我想我加上反接估计也加不了多少分所以我就没写了,所以这里我就只谈一下我的思路
对于反接的元器件,我如果检测到他是反接的,我会赋予它一个反接值,到最后输出的时候我会根据这个反接值判断他是否反接,若是反接我就先输出它的尾再输出他的头。
随后便是过载的问题,这里有一个小情况便是最好来根据电路来计算电流,因为如果根据分压来计算电流的话,开关等一些没有电压的电器是计算不了电流的,没有电流的赋值是根本不能判断,所以要计算整条电路的电流然后赋给这条电路的每一个电器
ouble zR = 0; double zI=0; for (int i = 0; i < rline.size(); i++) { zR = zR + rline.get(i).getR(); } if (zR == 0) { System.out.println("short circuit error"); System.exit(0); } if(exist) { zI=zv/zR; for (int i = 1; i < rline.size() - 1; i++) { rline.get(i).setI(zI); if (rline.get(i) instanceof FenDuanControler) { continue; } else if (rline.get(i) instanceof LianXuControler) { continue; } else if(rline.get(i) instanceof KaiGuan){ KaiGuan a=(KaiGuan) rline.get(i); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin() - zv * (a.getR() / zR)); }else if(rline.get(i) instanceof SkChuanglian){ SkChuanglian a=(SkChuanglian) rline.get(i); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin() - zv * (a.getR() / zR)); }else if (rline.get(i) instanceof BaiChi) { BaiChi a = (BaiChi) rline.get(i); a.getNowBrightness(zv * (a.getR() / zR)); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin() - zv * (a.getR() / zR)); } else if (rline.get(i) instanceof RiGuang) { RiGuang a = (RiGuang) rline.get(i); a.getNowBrightness(zv * (a.getR() / zR)); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin() - zv * (a.getR() / zR)); } else if (rline.get(i) instanceof DiaoFan) { DiaoFan a = (DiaoFan) rline.get(i); a.getNowSpeed(zv * (a.getR() / zR)); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin() - zv * (a.getR() / zR)); } else if (rline.get(i) instanceof LuoDiFan) { LuoDiFan a = (LuoDiFan) rline.get(i); a.getNowSpeed(zv * (a.getR() / zR)); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin() - zv * (a.getR() / zR)); }else if (rline.get(i) instanceof BingLine) { BingLine a = (BingLine) rline.get(i); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin() - zv * (a.getR() / zR)); if (a.getR() == 0) { continue; } else { setBing(((BingLine) rline.get(i)), zv * (a.getR() / zR)); } } else if (rline.get(i) instanceof ChuanLine) { ChuanLine a = (ChuanLine) rline.get(i); a.setBegin(rline.get(i - 1).getEnd()); a.setEnd(a.getBegin() - zv * (a.getR() / zR)); if (a.getR() == 0) { continue; } else { setChuan(((ChuanLine) a), zv * (a.getR() / zR)); } } } rline.get(rline.size() - 2).setEnd(0); for (int i = 0; i < QIKU.size(); i++) { if (QIKU.get(i) instanceof SkChuanglian) { SkChuanglian a = (SkChuanglian) QIKU.get(i); a.getNowOpenrate(QIKU); } } }
这是我对于电路的处理方法,里面可以看出是先算出这条电路的总电阻,然后算出这条电路的总电流,然后根据循环赋予给电路的每一个电器,同时在循环中也会计算每个电器的状态和给每个电器的引脚赋值
总的来说这次大作业的难度较高并且我自己没有规划好自己的时间导致我这次没有拿到理想成绩,我也会反思自己,改掉自己的一些坏毛病。
下面放一下类图
也是可以看出比上一次大作业复杂了很多,无论是方法还是类,也是看得我比较心累
可以看出老毛病,也是因为工具类事比较多,依旧是工具类的复杂度依旧爆表,甚至比上次加的更多,这的确是我代码的不足之处。
三,总结
说实话这八次大作业下来我收货真的非常的大,对于java各方面的东西,列如面向对象,继承,接口什么东西,类的设计,方法什么的了解与使用都更加的熟练更加的有章法,不会像开头一样觉得类就是C语言的结构体plus,我深深的了解这种程序设计方法的优越性,不止在于它的可跨平台性,怪不得越来越多的公司开始使用java语言,对于我个人来言较于C语言我更喜欢java,但是我对于代码的严谨性还是有一点不足,几次大作业一些情况也是到写完了才考虑到去加上的,严谨的思维对于一个程序员还是比较重要的,还有对于更高阶面向对象方法的使用还得去了解,这样才能更加的事半功倍。
对于课程的评价说实话我觉得很好,无论是大作业模式还是上课的情况我认为对于我上学期的C语言我学到的东西更多,我比较满意的就是大作业,能非常好的锻炼学生的能力,希望以后也能开设下去,其次我也有一些地方想吐槽,就是那个提交实验系统,很奇怪,我在上面的程序运行结果和我在idea和eclipse上运行的结果有些实验不一样,我估计是jdk版本的问题,还有最后一次实验都不让用javafx那不白整了吗,还有为什么实验四的提交时间比实验三还早,我不知道导致没交o(╥﹏╥)o,希望能升级一下那个系统,还有老师感觉很忙,每次问问题要么到上课也没回,要么要过很久才会,老师可以找几个人当助手来回答一些学生的问题就更好了。