OO作业第一单元总结
一、第一单元作业回顾
系列一作业分为三周进行,都是表达式求导,难度渐进。
第一次实现的是简单幂函数的求导,第二次加入了sin和cos两种三角函数,第三次实现了三角函数内的嵌套以及引入了表达式因子。
主要学到的东西有:
IDEA的操作使用(包括checkstyle/statics/MetricsReloaded等插件的使用)
正则表达式的使用
Biginteger
java中字符串处理
Arraylist的使用
继承与接口
java建立二叉树
递归分析的思路
二、程序结构分析
1.第一次作业
(1)类图
(2)规模
第一次作业的规模并不算大。
(3)复杂度
| Complexity metrics | 星期二 | 26 三月 2019 21:18:27 CST | |
|---|---|---|---|
| Method | ev(G) | iv(G) | v(G) |
| DeriPolynomia.main(String[]) | 7 | 24 | 24 |
| Term.addx(BigInteger) | 1 | 1 | 1 |
| Term.deri() | 1 | 1 | 1 |
| Term.getTerm1(String) | 1 | 1 | 2 |
| Term.getTerm2(String) | 1 | 1 | 1 |
| Term.getTerm3(String) | 1 | 1 | 1 |
| Term.getTerm4(String) | 1 | 1 | 2 |
| Term.getTerm5(String) | 1 | 1 | 1 |
| Term.getc() | 1 | 1 | 1 |
| Term.getx() | 1 | 1 | 1 |
| Term.numDeal(String) | 2 | 2 | 4 |
| Term.out() | 1 | 11 | 11 |
第一次作业可以明显看出我还停留在面向过程的思路,main方法一main到底,输入的处理直接都放在了main方法中,而没有新建一个类或者方法,这样导致我的main方法难以调试,容易出错。
2.第二次作业
(1)类图
(2)规模
第二次作业的规模比第一次变大了,但仍然可以接受。
(3)复杂度
| Complexity metrics | 星期二 | 26 三月 2019 21:15:57 CST | |
|---|---|---|---|
| Method | ev(G) | iv(G) | v(G) |
| Deri.checkS(String) | 4 | 10 | 13 |
| Deri.deal() | 8 | 16 | 16 |
| Deri.deri(Term) | 1 | 1 | 1 |
| Deri.getList() | 1 | 1 | 1 |
| Deri.getList2() | 1 | 1 | 1 |
| Deri.main(String[]) | 1 | 9 | 10 |
| Term.addChang(BigInteger) | 1 | 1 | 1 |
| Term.addCosC(BigInteger) | 1 | 1 | 1 |
| Term.addSinC(BigInteger) | 1 | 1 | 1 |
| Term.getChang() | 1 | 1 | 1 |
| Term.getCosC() | 1 | 1 | 1 |
| Term.getFlag() | 1 | 1 | 1 |
| Term.getSinC() | 1 | 1 | 1 |
| Term.getTerm(BigInteger,BigInteger,BigInteger,BigInteger) | 1 | 1 | 1 |
| Term.getTerm(String) | 10 | 9 | 10 |
| Term.getTerm1(String) | 14 | 14 | 14 |
| Term.getxdC() | 1 | 1 | 1 |
| Term.out() | 5 | 14 | 18 |
第二次作业在耦合度上比起第一次作业有所进步但仍然复杂度很高,我将对于输入的预处理放在了两个函数中checkS进行合法性的判断,deal进行split前的预处理,预处理之后进行项的处理,我把它放在了getTerm和getTerm1两个函数中,而没有再继续向下细分,这就导致我在处理项的过程中无法根据输入项的类型准确定位bug点,比较麻烦。
3.第三次作业
(1)类图
我把所有的运算符和因子都归并到Node类之中,并在Node类中实现了Ob对象,对于运算符,我只通过setType方法加以标识,而对于幂函数因子、三角函数因子、常数因子,我则实例化其对应Node中的Ob对象。
而在求导的时候,对于运算符Node,由于他最后返回的是几个符号和左右孩子求导结果的组合,因此我直接在Node类中实现dif接口完成此类求导,而对于因子类的Node,他返回的应是一个给予自身属性运算之后的新的Node,因此我又在Ob中预留了dif函数,让我的各因子——Chang/Mi/Tri去继承Ob类,实现各自的dif函数,这样的命名其实容易导致混淆,以后要加以注意。
(2)规模
第三次作业的规模较大,是一个不小的挑战。
(3)复杂度
| Complexity metrics | 星期二 | 26 三月 2019 21:06:46 CST | |
|---|---|---|---|
| Method | ev(G) | iv(G) | v(G) |
| Chang.dif() | 1 | 1 | 1 |
| Chang.getI() | 1 | 1 | 1 |
| Chang.setI(BigInteger) | 1 | 1 | 1 |
| Chang.setI(String) | 1 | 1 | 1 |
| Chang.setI(int) | 1 | 1 | 1 |
| Deal.get(char[]) | 1 | 1 | 1 |
| Deal.getEx(char[]) | 2 | 4 | 6 |
| Deal.getFa(char[]) | 10 | 10 | 10 |
| Deal.getNum(char[]) | 1 | 1 | 3 |
| Deal.getTe(char[]) | 2 | 4 | 6 |
| Deal.getcFa(char[]) | 2 | 6 | 6 |
| Deal.getsFa(char[]) | 2 | 6 | 6 |
| Deal.getxFa(char[]) | 2 | 3 | 3 |
| Deal.preDeal(String) | 1 | 28 | 31 |
| Deal.rpl(String) | 1 | 1 | 1 |
| Main.main(String[]) | 1 | 3 | 3 |
| Main.wrong() | 1 | 1 | 1 |
| Mi.dif() | 1 | 1 | 1 |
| Node.Node() | 1 | 1 | 1 |
| Node.Node(BigInteger) | 1 | 1 | 1 |
| Node.Node(char) | 2 | 2 | 10 |
| Node.dif() | 2 | 2 | 7 |
| Node.fdif() | 1 | 1 | 1 |
| Node.getData() | 1 | 1 | 1 |
| Node.getLchild() | 1 | 1 | 1 |
| Node.getRchild() | 1 | 1 | 1 |
| Node.getType() | 1 | 1 | 1 |
| Node.hdif() | 1 | 1 | 1 |
| Node.mdif() | 1 | 1 | 1 |
| Node.out() | 2 | 14 | 22 |
| Node.out_r() | 1 | 11 | 12 |
| Node.pdif() | 1 | 2 | 2 |
| Node.setData(Ob) | 1 | 1 | 1 |
| Node.setLchild(Node) | 1 | 1 | 1 |
| Node.setRchild(Node) | 1 | 1 | 1 |
| Node.setType() | 1 | 1 | 4 |
| Node.setType(char) | 2 | 2 | 7 |
| Node.setType(int) | 1 | 1 | 1 |
| Tri.dif() | 1 | 2 | 2 |
| Tri.getType() | 1 | 1 | 1 |
| Tri.setType(int) | 1 | 1 | 1 |
第三次作业我第一次使用了接口和继承,事实上由于对于这两个概念的了解不够深入,导致我的继承关系显得比较混乱,但总归是在不同的类之间建立了一定的逻辑关系。并且可以看出,虽然第三次作业在难度和代码量上比起前两次作业都有一个质的提升,但是我的方法的复杂度并没有随之有一个很大的变化,这也得益于继承和接口的使用,也正是在这一次作业开始,我觉得自己开始对于“面向对象”的思维方式有了新的认识。
至于方法复杂度,preDeal我复用了部分前两次作业的代码,虽然比较复杂但对于我个人而言理解并没有问题,但如果是在团队开发的过程中,这样的方法自然是要尽量避免的。
三、bug分析
1.第一次作业
没有在公测与互测中发现bug
2.第二次作业
在优化输出的过程中,为了实现将‘1*其他因子’这么一个式子中的‘1*’忽略,我先把整个式子输出到一个数组,把这个数组转成字符串,再把所有的‘1*’抹掉,却忽略了判断被抹掉的‘1’是不是真的是独立的因子,导致‘x^11*5’中的‘1*’也被抹掉,就这么一个bug,导致我被扣将近四十分,可谓损失惨重。
3.第三次作业
在读取因子的时候,如果碰到运算符+或-之后,我就直接将之后的内容作为常数因子进行处理,忽略了之后是表达式因子的情况,因此对于‘-(x)’这样的表达式我会报错WF,导致强测和互测中都出现了bug。
四、互测策略
我在互测之中一般按三步进行:
1.利用自己在构造代码过程中发现的容易出错测试集进行测试。
2.阅读代码,尝试找出bug
3.利用脚本进行大量测试
个人测试集测试
这一步直接利用自己在构造代码时准备的测试集进行测试,其中大部分其实是我自己的代码在完善过程中出现bug的测试点,事实证明大家易犯的错误实际上是类似的,第一次作业和第三次作业我都在这一步发现了同屋其他人的bug。
阅读代码
对于同时测试6、7个人的互测而言,阅读代码实际上有着不小的难度,我只在第一次作业,代码规模较小的情况下通过阅读代码的方式发现了一位同学的bug,在后两次作业的互测过程中都没有发现bug,这一方面是因为时间有限,没有办法非常细致地阅读每位同学的代码,另一方面也有着先入为主,被别人代码引导了思路的原因。
但阅读代码也不仅仅是为了寻找bug,也可以使我们得到其他同学代码的启示,我在第一次作业处理输入时是采用的‘匹配-替换-再匹配’的模式,而在互测过程中,我发现有不少同学采用的是‘先进行符号处理,再用+进行split,再分别处理各个项’的方式,这给我的第二次作业的处理提供了很大的帮助。
脚本测试
利用bash脚本进行批量测试,再对于输出结果进行肉眼比对,有同学在得到输出结果之后利用matlab或者sympy进行比对,很遗憾没能掌握这样的测试方法。
五、Applying Creational Pattern
对于java设计模式我了解的并不是很多,通过大致查阅资料我发现自己的设计有的地方具有抽象工厂模式的特征,有的地方又有着建造者模式的特征,总的来说前三次作业我都有一种埋头去干的感觉,在顶层设计上并没有提前做好准备,显得比较混乱,这也导致我在debug上花费了大量的时间,这一点需要我在之后的作业中进行改进。
OO作业第一单元总结的更多相关文章
- 北航oo作业第一单元小结
前言 在经过了三次艰辛的oo作业后,oo课程的第一单元告一段落,这一单元,我作为一个oo小白,开始了解oo的编程思想,也有了自己的一点心得体会.把笔粗成字,不当之处,还请各位大佬多多指教. 一.分析程 ...
- OO面向对象第一单元总结
OO面向对象第一单元总结(表达式求导) 写在前面: 魔鬼课程oo第一单元终于结束,当终究要落笔总结,竟不知从何写起…… 回首再去看第一次的作业,你会满足于那时的幸福,或许,这就是成长吧! 千言万语,一 ...
- OO第一次博客作业--第一单元总结
OO第一单元总结 面向对象设计与构造的第一单元,对“面向对象”的概念还根本不理解不熟悉,只觉得需要“分模块”,但不知道怎么分,分多少模块,怎么根据需要的模块的功能建立类.学习的进度又太慢,根本跟不上出 ...
- BUAA OO 2019 第一单元作业总结
目录 总 架构 Controller Model 输入处理 代码静态分析 行数 方法复杂度 UML 类图 优点 缺点 坑 输入 非法的空白字符 输入的简并处理 运算 浅拷贝 可变类型与不可变类型 ...
- 北航oo作业第二单元小结
类的设计: 首先,我对我的思路进行整体的说明,由于我的三次作业,思路是继承的,所以做总体的说明 第一, Main类,Main类自身并没有功能,他的功能只是构造需要的电梯线程和输入线程. 其中,第三 ...
- OO作业第二单元总结
目录 一.设计策略 1 2 3 二.程序分析 1 2 3 S.O.L.I.D分析 三.Bug分析 1 2 3 四.互测策略 五.心得体会 一.设计策略 1 第一次完成的是一个傻瓜电梯,简单来说,就是来 ...
- OO第四单元——基于UML的UML解析器总结&OO课程总结
OO第四单元--基于UML的UML解析器总结&OO课程总结 前言:一学期愉快(痛苦)的OO课程学习结束了,OO几个单元作业都各有特色,实验也各有特色,仔细回味起来,不再是单纯的敲代码(但自己还 ...
- OO第四单元总结暨期末总结
OO第四单元总结暨期末总结 目录 OO第四单元总结暨期末总结 第四单元三次作业架构与迭代 整体感受 HW1 HW2 HW3 四个单元架构设计与方法演进 Unit1 Unit2 Unit3 Unit4 ...
- OO第一单元作业总结
oo第一单元的作业是对多项式的求导.下面就是对三次作业分别进行分析. 第一次作业 分析 第一次作业相对来讲比较简单,甚至不用面向对象的思想都能十分轻松的完成(实际上自己就没有使用),包含的内容只有常数 ...
随机推荐
- 求斐波那契数列第n位的几种实现方式及性能对比(c#语言)
在每一种编程语言里,斐波那契数列的计算方式都是一个经典的话题.它可能有很多种计算方式,例如:递归.迭代.数学公式.哪种算法最容易理解,哪种算法是性能最好的呢? 这里给大家分享一下我对它的研究和总结:下 ...
- this解惑
前言 要正确理解this,首先得理解执行上下文,这里推荐汤姆大叔的执行上下文,因为this是在运行代码时确认具体指向谁,箭头函数除外. 全局作用域中的this node: 每个javaScript文件 ...
- shader Category
Category:是渲染命令的逻辑组,着色器可以多个子着色器,他们需要共同的效果 // Copyright 2014 Google Inc. All rights reserved. // // Li ...
- Unity手游之路自动寻路Navmesh之入门
http://blog.csdn.net/janeky/article/details/17457533 现在的大部分mmo游戏都有了自动寻路功能.点击场景上的一个位置,角色就会自动寻路过去.中间可能 ...
- Java-GC-标记压缩算法
标记压缩算法 其分为两个阶段标记阶段,和压缩阶段.其中标记阶段和标记清除算法的标记阶段是一样的. 对压缩算法来说,他的工作就是移动所有的可达对象到堆内存的同一区域中,使它们紧凑的排列在一起,从而将所有 ...
- [LOJ 2022]「AHOI / HNOI2017」队长快跑
[LOJ 2022]「AHOI / HNOI2017」队长快跑 链接 链接 题解 不难看出,除了影响到起点和终点的射线以外,射线的角度没有意义,因为如果一定要从该射线的射出一侧过去,必然会撞到射线 因 ...
- MySQL 实现字符串换行
target_describe字段值中包含 :[ 这两个特殊的字符 ,想要在字符之间加换行 需要插入CHAR(10) ),'[')) UPDATE ew_pm_project_red_detail S ...
- 简单ui
UI继承 jQuery 简易使用特性,提供高度抽象接口,短期改善网站易用性. jquery UI 是一个建立在 jQuery JavaScript 库上的小部件和交互库,您可以使用它创建高度交互的 W ...
- Minor GC ,Full GC 触发条件
Minor GC ,Full GC 触发条件 Minor GC触发条件:当Eden区满时,触发Minor GC. Full GC触发条件: (1)调用System.gc时,系统建议执行Full GC, ...
- AJPFX关于JDK,JRE,JVM的区别与联系
很多朋友可能跟我一样,对JDK,JRE,JVM这三者的联系与区别,一直都是模模糊糊的. 今天我们来整理下三者的关系. JDK : Java Development ToolKit(Java开发工具包) ...