一,前言
第四到六次大作业结束了,也很轻信自己都拿到了满分,题目的难度依旧为我们考虑没有设置太高,题目量级也还可以,对于知识点的应用非常的具有综合性,主要考差了我们对于知识点的应用的对于程序设计的综合能力。
二,设计与分析&踩坑&改进想法
1,第四次大作业
对于第四次大作业的大boss迭代练习题,说实话对于第三次迭代所做出的改动并没有很大,主要便是在第三次大作业的基础上加了一些比较新的题型,并对他们的大份规则进行了一定的定义以进行此次迭代,之前的代码绝大部分都是可以继承过来的,需要修改的部分就是增加这些的题目类,修改增添根据题型来的评分的规则还有最后打分的明细规则。我对其主要的思路就是现将所有的输入进行存储,然后进行有顺序的先后处理,对于题目处理后有相应的题库进行存储,对于试卷处理后也有相应的试卷库,答卷处理后也有答卷库,随后便是对于答卷的批改打分输出结果,其中一些重要的部分我想列举
public String judgeAnswer(int n, String anwser1) { if(questionList.get(n) instanceof Classic) { if (questionList.get(n).getAnswer().equals(anwser1)) { return "true"; } else { return "false"; } } else if(questionList.get(n) instanceof Gapfill) { if(questionList.get(n).getAnswer().contains(anwser1)&&!questionList.get(n).getAnswer().equals(anwser1)) { return "partially correct"; }else if(questionList.get(n).getAnswer().equals(anwser1)){ return "true"; }else{ return "false"; } }else if(questionList.get(n) instanceof Multiple) { String[] answer11 =anwser1.split(" "); int a=0; int b=0; for (int i = 0; i < answer11.length; i++) { for (int j = 0; j < ((Multiple) questionList.get(n)).getAnswerlist().length; j++) { if(!((Multiple) questionList.get(n)).getAnswerlist()[j].equals(answer11[i])) { b++; }else{ a++; } } if(b==((Multiple) questionList.get(n)).getAnswerlist().length){ return "false"; } b=0; } if(a== ((Multiple) questionList.get(n)).getAnswerlist().length){ return "true"; }else { return "partially correct"; } }else{ return "false"; } }
这是我对于试卷打分时的对于题目修改的方法,个人认为这是我此次大作业比较重要的代码之一,其会根据传进来的题目索引进行题目寻找后先进行类型的判别,然后进行相应的给与的答案批改并给与批改结果。这一部分代码的写入对于之后的试卷打分的正确性奠定了一定的基础。
public String[] getResult() { for (int j = 0; j < model.getQuestionList().size(); j++) { result[j] = "answer is null"; grade[j] = 0; } for (int i = 0; i < answerList.size(); i++) { if(numList.get(i)>model.getQuestionList().size()){ continue; } if(model.getQuestionList().get((numList.get(i))-1).isExist()&&model.getQuestionList().get((numList.get(i))-1).isDel()==false) { result[(numList.get(i)) - 1] = model.getQuestion((numList.get(i)) - 1) + "~" + answerList.get(i) + "~" + model.judgeAnswer((numList.get(i)) - 1, answerList.get(i).trim()); if (model.judgeAnswer((numList.get(i)) - 1, answerList.get(i).trim()).equals("true")) { grade[(numList.get(i)) - 1] = model.getGrade().get((numList.get(i)) - 1); }else if(model.judgeAnswer((numList.get(i)) - 1, answerList.get(i).trim()).equals("partially correct")){ grade[(numList.get(i)) - 1] = (model.getGrade().get((numList.get(i)) - 1))/2; } }else if(model.getQuestionList().get((numList.get(i))-1).isExist()&&model.getQuestionList().get((numList.get(i))-1).isDel()==true){ result[(numList.get(i)) - 1]="the question "+(numList.get(i))+" invalid~0"; }else if(model.getQuestionList().get((numList.get(i))-1).isExist()==false){ result[(numList.get(i)) - 1]="non-existent question~0"; } } return result; }
这一部分是我对于一张答卷评判结果的输出方法,其根据自己的题目集合以及答案集合传入判别方法来进行正确性的判断并将最后的结果总结到一个字符串数组里准备输出。
- 这里比较重要的思维便是如何确定哪些的答案是anwser is null的情,因为去除一些特殊的情况很多情况下anwser is null都是结果,而如果将这些结果一一找出来将会十分的麻烦,因此我觉得先按照试卷题目的数目先创一个字符串数组并且全部赋值anwser is null然后对于不是的情况来修改,事实证明我的选择是正确的
其次便是在写这个时遇到的问题,因为这里需要考虑的情况比较多,所以对于这一部分的修改对于我时间的花费也是比较的多
- 其一便是试卷题目数超出学生作答的答案数和学生作答的答案数超出试卷的题目数,对于这个一个判断是解决不了的,但我当初没有想到这个情况,导致运行时会出现超出界限的情况发生,然后我对于代码调试找到了这个问题并修正
- 其二便是一些空格的问题,对于第三次迭代我有几分没有拿到并且我找不到我错在哪里,这次我找到了,就是我在答案判决的时候去掉了答案两边的空格但是输出的时候忘了去掉了所以有几分没拿到。
其三便是以我现在的眼光来看代码对于对象的应用有些冗杂,对于一些对象的引用我完全可以再创一个对象将其地址托付给他但是那时的我却是硬写,导致代码看似很高级但是内行人应该都知道这是新手行为
随后放下这次大作业的类图
2,第五次大作业
第五次大作业说实话看第一眼的时候并没有什么好的想法,因为脑子好像没有什么东西是可以将一堆东西串在一起形成一个类似于电路的结构的,java又没有链表,但是设备的设计我是有思路的,于是我决定先设计设备然后再想怎么把他们穿在一起包括电压传递之类的东西,按照我的想法我设备的设计会有四层继承,最高层便是总设备,就是设备这个类,随后的继承就是调节设备类和电路设备类,然后就是闭合开关,分档调节器,连续调节器继承调节设备类,其他诸如白炽灯,风扇什么的东西继承于电路设备类,在设计的时候我同时想好了,用集合来存放设备形成电路,同时我还看到老师构建的tool类使得主函数十分简洁美观,于是我便也想借鉴一下
public class Main { public static void main(String[] args) { Tool tool = new Tool(); tool.input(); tool.creatLines(); tool.process(); tool.output(); } }
这是程序设计完后的主函数,是不是十分的nice(*^▽^*),然后便是我个人认为比较重要的一些函数
public void setVAndConditiion(){ boolean exist=true; for(int i=1;i<line.size()-1;i++){ if(line.get(i) instanceof KaiGuan){ if(((KaiGuan) line.get(i)).getCondition()==0){ for (int j = 1; j < line.size()-2; j++) { line.get(j).setBegin(0); line.get(j).setEnd(0); } exist=false; } } } if(exist){ for (int i = 1; i < line.size()-1; i++) { if(line.get(i) instanceof KaiGuan){ KaiGuan a=(KaiGuan)line.get(i); a.setBegin(line.get(i-1).getEnd()); a.setEnd(line.get(i-1).getEnd()); line.set(i,a); }else if(line.get(i) instanceof FenDangControler){ FenDangControler a=(FenDangControler) line.get(i); a.setBegin(line.get(i-1).getEnd()); a.setEnd(a.getBegin()*(0.3)*a.getGears()); line.set(i,a); }else if(line.get(i) instanceof LianXuControler){ LianXuControler a=(LianXuControler) line.get(i); a.setBegin(line.get(i-1).getEnd()); a.setEnd(a.getBegin()*a.getGears()); }else if(line.get(i) instanceof BaiChi){ BaiChi a=(BaiChi) line.get(i); a.setBegin(line.get(i-1).getEnd()); a.setEnd(0); a.getNowBrightness(a.getBegin()-a.getEnd()); line.set(i,a); }else if(line.get(i) instanceof RiGuang){ RiGuang a=(RiGuang) line.get(i); a.setBegin(line.get(i-1).getEnd()); a.setEnd(0); a.getNowBrightness(a.getBegin()-a.getEnd()); line.set(i,a); }else if(line.get(i) instanceof DiaoFan){ DiaoFan a=(DiaoFan) line.get(i); a.setBegin(line.get(i-1).getEnd()); a.setEnd(0); a.getNowSpeed(a.getBegin()-a.getEnd()); line.set(i,a); } } } }
其一便是电路设备的根据传过来的电压来设定情况的行数,这次我是按照引脚的电压传递来计算电路设备情况的,然后这里我并没有亦是到我用于接收电路设备的和我电路设备是存放的一样的地址,于是在设置状态完后我还替换回去(*/ω\*),这也是对基础概念不牢靠的结果
说实话写这次大作业的时候我一直在往后想怎么样才能于之后的大作业兼容好不用改什么东西,所以有些地方会写的少许复杂(听说很多人这次因为只有一个电器而直接判断电器都没有串在一起,感觉他们这次轻松了但下次肯定要大改),事实证明这点心思没有被辜负(下次大作业直接一遍过(*^▽^*))
放一下这次代码的设计类图
也是因为tool类的处理太多导致复杂度有点高
3,第六次大作业
第六次大作业相较第五次大作业加上了并联的情况一开始并没有想到怎么去写,随后想到可以把并联电路和串联电路都做成电器元件,并联电路里面有串联电路的集合,这样就解决了并联的问题,我将所有原件放进一个集合方便排序,把所有电路放在一个集合方便并联电路取串联电路。同时这次迭代我也改变了电路元件状态设置的策略,原先的从上一个引脚获取电压的太过于麻且容易出错,这次因为加入了电阻的概念我觉得用分压来写,使得代码更加有效
public void setZong(double zv){ double zR=0; for (int i = 0; i < rline.size(); i++) { zR=zR+rline.get(i).getR(); } for (int i = 1; i < rline.size()-1; i++) { if(rline.get(i) instanceof BaiChi){ BaiChi a=(BaiChi) rline.get(i); a.getNowBrightness(zv*(a.getR()/zR)); }else if(rline.get(i) instanceof RiGuang){ RiGuang a=(RiGuang) rline.get(i); a.getNowBrightness(zv*(a.getR()/zR)); }else if(rline.get(i) instanceof DiaoFan){ DiaoFan a=(DiaoFan) rline.get(i); a.getNowSpeed(zv*(a.getR()/zR)); } else if (rline.get(i) instanceof LuoDiFan) { LuoDiFan a=(LuoDiFan) rline.get(i); a.getNowSpeed(zv*(a.getR()/zR)); }else if(rline.get(i) instanceof BingLine){ BingLine a=(BingLine) rline.get(i); if(a.getR()==0){ continue; }else { setBing(((BingLine) rline.get(i)), zv * (a.getR() / zR)); } } } }
这是状态设置的方法,可以发现明明设备更多了但是代码也减少了很多,就是因为我对于对象地址的应用的了解更进了一步,同样重要的还有并联电路的状态设计
public void setBing(BingLine bl,double bv){ for (int i = 0; i < bl.getLine().size(); i++) { ChuanLine c=((ChuanLine)bl.getLine().get(i)); if(c.isExist()) { for (int j = 0; j < c.getLine().size(); j++) { if (c.getLine().get(j) instanceof BaiChi) { BaiChi a = (BaiChi) c.getLine().get(j); a.getNowBrightness(bv * (a.getR() / c.getR())); } else if (c.getLine().get(j) instanceof RiGuang) { RiGuang a = (RiGuang) c.getLine().get(j); a.getNowBrightness(bv * (a.getR() / c.getR())); } else if (c.getLine().get(j) instanceof DiaoFan) { DiaoFan a = (DiaoFan) c.getLine().get(j); a.getNowSpeed(bv * (a.getR() / c.getR())); } else if (c.getLine().get(j) instanceof LuoDiFan) { LuoDiFan a = (LuoDiFan) c.getLine().get(j); a.getNowSpeed(bv * (a.getR() / c.getR())); } else if (c.getLine().get(j) instanceof BingLine) { BingLine a = (BingLine) c.getLine().get(j); if (a.getR() == 0) { continue; } else { setBing(((BingLine) c.getLine().get(j)), bv * (a.getR() / c.getR())); } } } } } }
根据并联电路内的电路数循环设置状态,同时有之前从分压获取的整个并联电路的电压状态更加的方便我去计算每个电器元件的状态
几个比较卡我的点就是
- 并联电路的状态如何去设置,前面也说了我是先计算并联电路的电阻然后获取分压在计算内部的情况,这里就会有一些问题,就是并联电路的情况的多样性
- 其一便是所有开关都关闭的情况,这种情况要将整个的电路锁死
- 其二便是关的只剩一条电路的情况,这种情况要将并联电路当做串联电路来处理,并联电路计算阻值的方法于此不通用
- 其三便是短路的情况,就是并联电路内存在一条分路内没有任何电器并且开关是开着的那么电流就会直接从这里走而不走其他地方
好的地方就是这些都在写的时候逐渐考虑到了,写到一半想起一个就加上一个,好在想全了
还有一个地方就是排序输出,将所有放在电路里的电器放在一个集合里方便排序也是理解对象地址后进行的改革,对于我的排序输出有着很大的帮助,当然排序的依据也不是按照名字来排,这样过于冗杂,于是我将所有的电器都加了一个属性就是排序值,这个值越高他的地位就更高,就越前面输出,这个属性我给其取名为rank
这里也有看出会比上一次大作业复杂一点,类也会更多
这里也可以看出因为tool函数处理了输入,创造电路,状态设置,输出等情况,所有他的复杂度相较于其他类也是个断崖式增长,也是可以有优化的地方
三,总结
这三次大作业说实话,对于我自己来说,我学到的东西应该比前三次作业更多,包括对于主函数的编程其实完全可以使用tool类或者agent类来完成,使主函数更加的简洁美观同时更加便于维护修改,还有类与类之间的联系包括继承什么的,类的状态设计,只要属性足够一个类按理可以设置很多很多状态,最主要的便是地址,类的地址,除了基本属性对于对象的接受基本都是地址的传递,传过来的不是具体的对象而是对象所存在的空间的地址,这是十分重要的一点,懂了这点便可以让一个类在不同地方以不同的称号出现,一改俱改,这使得很多地方只要存了,在存进另一个复杂的地方就不用再去取出来,可以去之前那个地方直接修改更加的方便。
学到很多,下次大作业我也会将这些应用,争取下一次大作业写的更好!