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第一单元的作业是对多项式的求导.下面就是对三次作业分别进行分析. 第一次作业 分析 第一次作业相对来讲比较简单,甚至不用面向对象的思想都能十分轻松的完成(实际上自己就没有使用),包含的内容只有常数 ...
随机推荐
- 洛谷P1368 均分纸牌(加强版)
P1368 均分纸牌(加强版) 题目描述 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,纸牌总数必为 N 的倍数.可以在任一堆上取1张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取 ...
- 静态文件与APP
目录 静态文件的配置和使用 什么是静态文件? 为什么使用静态文件 如何配置,使用静态文件 静态文件相关(动态配置) app创建预注册 app指什么? 创建一个APP 注册app app文件作用 app ...
- C# 主要运算符中的成员访问(?.)
在开发过程中,我遇到了一种null 条件成员访问的写法,开始不太理解,之后专门查了微软的官方文档,下面是具体内容: 三种成员访问的三种形式 (1)x.y:成员访问. (2)x?.y:null 条件 ...
- js框架:vue
vue是一套用于构建用户界面的渐进式框架,vue被设计为可以自底向上逐层应用,核心库只关注图层 待续.......
- PJzhang:搜索引擎高级语法与渗透测试
猫宁!!! 参考链接: https://www.freebuf.com/articles/network/169601.html https://www.jianshu.com/p/f8062e2cc ...
- JS高级学习历程-2
1.dom操作,利用dom创建无序列表.并追加到body里边,里面要求至少有四个项目. <!DOCTYPE html> <html lang="en"> & ...
- selenium基础操作
selenium 1.打开和关闭网页 #!/usr/bin/env python # -*- coding:utf-8 -*- from selenium import webdriver drive ...
- 2017 Multi-University Training Contest - Team 7 Just do it
http://acm.hdu.edu.cn/showproblem.php?pid=6129 题意:一次操作就是i从1~n有 A[i]=A[i]^A[i-1]^A[i-2]...^A[1] 那么这样操 ...
- Jenkins+Gitlab+Ansible自动化部署(三)
接Jenkins+Gitlab+Ansible自动化部署(一)https://www.cnblogs.com/zd520pyx1314/p/10210727.html 和(二)https://www. ...
- 专题《一》mysql优化 ---------主从复制,读写
主从复制是mysql自带的功能,读写分离用第三方插件 主从复制作用:读写分离(mycat),数据备份,高可用,集群 原理:二进制sql执行文件-----insert,update,delete,cre ...