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第一单元的作业是对多项式的求导.下面就是对三次作业分别进行分析. 第一次作业 分析 第一次作业相对来讲比较简单,甚至不用面向对象的思想都能十分轻松的完成(实际上自己就没有使用),包含的内容只有常数 ...
随机推荐
- CentOS软件包管理
rpm安装包管理 指令 说明 rpm -i XX.rpm 安装XX.rpm软件包 rpm -qa XX 查看XX软件包安装的所有文件 rpm -e XX 卸载XX软件包 yum管理软件 指令 说明 y ...
- [openjudge] 2797最短前缀 Trie
描述 一个字符串的前缀是从该字符串的第一个字符起始的一个子串.例如 "carbon"的字串是: "c", "ca", "car&q ...
- 51nod1127(尺取法)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1127 题意:中文题诶- 思路:尺取法 维护一个队列,若当前队 ...
- 剑指Offer的学习笔记(C#篇)-- 构建乘积数组
题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不 ...
- 判断iphone 屏幕大小宏定义
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) #define IS_IPHONE (UI_USER_I ...
- vue路由的四种传值
第一种:props 配置: 组件内定义: props: ['id'] 路由映射配置,开启props:true : { path: '/user/:id', component: User, props ...
- NET Core项目
在IIS上部署你的ASP.NET Core项目 概述 与ASP.NET时代不同,ASP.NET Core不再是由IIS工作进程(w3wp.exe)托管,而是使用自托管Web服务器(Kestrel) ...
- 转 简单聊聊IT软件项目的风险及应对
https://www.jianshu.com/p/b347adca87a6 前言 上段时间在一家演讲俱乐部做即兴演讲主持人,聊的就是风险管理,与会的小伙伴分享了不同行业的风险问题,令人受益匪浅,今天 ...
- PostgreSQL 导出导入表中指定查询数据
创建一临时表: create table test_view as select * from test where date(to_timestamp(endtime))>='2012-09- ...
- 汉柏杯&&政治生日6月5日&&端午节
(一)汉柏杯 前不久汉柏杯2019年计算机设计大赛由我校承办,参加了软件应用开发组竞赛.开发了一个基于微信公众号的求职招聘系统,虽然很low但是貌似还是进了国赛,大概八月十号去安徽芜湖参加国赛决赛.据 ...