OO第一单元作业小结
前言
第一单元的主题是表达式求导,第一次作业是只带有常数和幂函数的求导,第二次作业加入了正余弦函数,第三次作业又加入了表达式嵌套,难度逐渐提升。总体来说前两次作业还易于应对,而第三次作业做得相对有些艰难。而且这其中还有很多巧合,第二次作业延时到了周三上午,而我在周二晚睡觉前经过本地测试又找到一处致命BUG,一直改到一点才交上;第三次作业一开始中测的最后一个点一直没有通过,周二找了一天本来已经放弃,后来得知作业又延时到周三中午,成功在周三上午找到了那处BUG,并正好用完十次无偿提交次数,终于过了全部中弱测。若不是这两次延时,第一单元的作业恐怕已经崩掉了。
一、三次作业的代码分析
1、第一次作业
(1)类图与复杂度:

(2)程序分析
仅用了两个类。主类Derivation仅包括主函数入口。类Exp中包含一个private属性str[],它是用来储存项的字符串数组;四个方法,其中Exp()是构造方法,同时进行格式合法性判断和拆项,getLength()用来获得str的元素个数,diff()用于处理每一项、求导并将结果中的同类项合并,pri()用于输出求导结果。
可以看出diff()的方法规模较大,因为这个方法同时具有按情况处理项、求导、合并同类项三个功能,可以将这三个功能拆成两个或三个方法来写。Derivation类约有35行代码,Exp类约有115行代码,总共约150行代码。
(3)优缺点分析
第一次作业我的代码总体还是比较面向过程,基本上按照C语言的模式去写的,面向对象的思想不够深刻。
2、第二次作业
(1)类图与复杂度


(2)程序分析
第二次作业的整体思路是处理表达式后,分别获得每一项的系数、x的指数、sin(x)的指数、cos(x)的指数四个ArrayList,求导时则是系数乘以某一个因子求导的结果再乘以其他因子。
总共有Derivation2、Exp、Diffx、Diffcos、Diffsin五个类,其中Derivation2包含主函数的入口,Exp用于判断表达式合法性、处理表达式并进行求导结果的输出,Diffsin、Diffcos、Diffx分别是对三类函数的求导处理。
可以看出,Diffx、Diffsin、Diffcos三个类中的pri函数(对求导结果的输出函数)代码复杂度较大,因为其中为了简化输出结果,用了很多if-else语句判断指数为0、1、2等以及指数为负等情况。还有Exp类中的getList()方法(用于获得各个因子的指数)也用了很多if-else语句判断三种因子是否省略指数等情况。
另外,Exp中的private属性过多,因为判断表达式合法性的方法超过了60行,我就将三种因子及常数因子的正则表达式写到了类的private属性里。
(3)优缺点分析
写第二次作业时其实并没有完全理清思路,很多方法构造的比较复杂,甚至有为了缩减方法行数将方法内的变量移到类的属性中的草率决定。
3、第三次作业
(1)类图与复杂度

(2)程序分析
第三次作业的整体思路是先将输入的表达式进行递归判断是否合法,然后进行链式求导,其中存在对各种因子求导、对项求导与对表达式求导的相互调用。
共九个类,Main包含主函数入口,Exp用于递归判断表达式合法性,Factor作为父类,Da、Dx、Dsin、Dcos、Dterm、Dexp都是Factor的子类,分别用于对常数、幂函数、正弦函数、余弦函数、项、表达式求导。
可以看出方法复杂度最高的是每个子类中的diff()方法(求导函数)以及Exp中的exchange()方法(递归去括号)和judge()方法(判断合法性),因为其中都用了很多if-else语句判断各种情况。
(3)优缺点分析
个人认为第三次作业还是存在一些优点的,比如我独立完成了递归判断合法性代码的编写。缺点是没有对结果进行化简,我的程序是变求导边直接打印结果的,其中只有一些简单的指数为0、1、2等情况的简化,其它的都是直接输出,还存在很多无意义的括号。
二、三次作业的BUG分析
1、第一次作业
第一次作业强测中有一处BUG,互测没有被找出BUG。
第一次作业本来也比较简单,我也做了结果的简化,包括首项为负时正项提前的化简也做了,本以为应该一百分,结果强测有两个点没过。
这两个点都源于同一处BUG,我在求导之后合并同类项时,忽略了合并后系数为零的情况,也就是说我将系数为零的项也输出了,但本应该只是扣性能分,结果应该是正确的,但我在连接每一项时只判断了系数大于0时添上+号,因为系数为负时输出的BigInteger会自带符号,所以我对于系数为0项的输出前没有加减号,也就产生了类似于x^20*x的不合法结果。这个BUG本质上还是粗心了,只考虑了输入时将系数为0的项忽略,而没将合并后系数为0的项排除。
2、第二次作业
第二次作业强测中有一处BUG,互测没有被找出BUG。
我的求导思路是对每一项的每一个因子分别求导,并将某个因子求导结果乘以其它因子,而我判断了如果某个因子求导结果的指数为0,将其忽略,但我在输出时却无条件地在求导因子外的其他因子前输出一个*号,也就产生了类似于+*x的不合法结果。
还有一点值得一提的是我在周二极限de到凌晨一点的BUG,那就是我在对输入的表达式进行同类项合并时,由于我用了四个ArrayList分别储存每一项的系数、幂函数指数、正弦函数指数与余弦函数指数,我在判断同类项时写成了只要在三个存指数的ArrayList中找到了与当前项各个指数相同的元素,就将系数相加而不添加新的指数元素。但这样假如输入一个x+sin(x)+cos(x)+x*sin(x)*cos(x)的表达式时,就会将第四项判断为之前出现过同类项,而将表达式化简成2*x+sin(x)+cos(x)。所以在判断同类项时,应该判断在ArrayList中是否有当前项的各个指数全都对应存在的元素,如果有才是真正的同类项。
3、第三次作业
第三次作业强测与互测中都没有被找出BUG。
这里分享我当时中测最后一个点死活de不出来的BUG。我在递归进行合法性判断时,先判断括号中的内容是否合法,若合法将括号及其中的内容直接替换为字母x或字母e(换为e即代表当前括号及其中的内容是一个表达式因子)。我在替换时用到了replace函数,但是replace会一次性替换所有相同子串,例如输入的表达式是(x)+sin(x),我就会在第一次替换时直接将原式替换为e+sine,即认为正弦函数括号中为一个裸的表达式,从而判断为WF。所以应该用replaceFirst函数仅替换刚找到的子串。这里还需要注意的一点是,replace函数替换的是子串,而replaceFirst函数替换的是第一处符合正则的子串,也就是说,在找到一个括号子串(设为字符串s),在用replaceFirst函数式应先将s中的+、(、)等字符前加上转移符,以将s转换成正则表达式再使用replaceFirst函数。
三、互测时找BUG的策略(love and peace)
由于本人很菜,前两次互测时都是先手动输入一些易错数据以及自己写代码时曾经出现BUG的数据来判断输出的正确性,然后就是肉眼debug了,即阅读被测代码的设计结构构造相应数据。这样的策略虽然效率不是很高,不过也能找到明显的BUG。在第三次互测时做了一次伸手党,从隔壁大佬那里整来了一个对拍器,找BUG的效率的确高很多。
四、Applying Creational Pattern
每次作业中都有很多方法有很多if-else语句,其实有的可以拆分成多个方法去写。
第三次作业写的时候对继承的用法还不够熟悉,程序的实现对继承的依赖并不大,也并没有使用接口,存在重构的必要。
另外希望可以通过学习自己写出对拍器。
OO第一单元作业小结的更多相关文章
- 【OO学习】OO第一单元作业总结
OO第一单元作业总结 在第一单元作业中,我们只做了一件事情:求导,对多项式求导,对带三角函数的表达式求导,对有括号嵌套的表达式求导.作业难度依次递增,让我们熟悉面向对象编程方法,开始从面向过程向面向对 ...
- 【作业1.0】OO第一单元作业总结
OO第一单元作业已全部完成,为了使这一单元的作业能够收获更多一点,我回忆起我曾经在计算机组成课设中,经常我们会写一些实验报告,经常以此对实验内容反思总结.在我们开始下一单元的作业之前,我在此对OO第一 ...
- OO第一单元作业总结——表达式求导
OO第一单元作业总结 第一次作业 基于度量分析代码结构 基本算法 第一次作业是简单多项式导函数求解,不需要对输入数据的合法性进行判定, 基本思想是用 (coeff, expo)表示二元组 coeff* ...
- OO第一单元作业总结
oo第一单元的作业是对多项式的求导.下面就是对三次作业分别进行分析. 第一次作业 分析 第一次作业相对来讲比较简单,甚至不用面向对象的思想都能十分轻松的完成(实际上自己就没有使用),包含的内容只有常数 ...
- 北航OO第一单元作业总结(1.1~1.3)
经过了三次作业之后,OO第一单元告一段落,作为一个蒟蒻,我初步了解了面向对象的编程思想,并将所学内容用于实践. 一.第一次作业 1.架构分析 本次作业需要完成的任务为简单多项式导函数的求解.表达式仅支 ...
- OO第二单元作业小结
前言 转眼已是第九周,第二单元的电梯系列作业已经结束,终于体验了一番多线程电梯之旅. 第一次作业是单电梯的傻瓜调度,虽然是第一次写多线程,但在课程PPT的指引下,写起来还是非常容易:第二次作业是单电梯 ...
- 2019北航OO第一单元作业总结
一.前三次作业内容分析总结 前言 前三次作业,我提交了三次,但是有效作业只有两次,最后一次作业没能实现多项式求导的基本功能因此无疾而终,反思留给后文再续,首先我介绍一下这三次作业,三次作业围绕着多项式 ...
- OO第一单元作业——魔幻求导
简介 本单元作业分为三次 第一次作业:需要完成的任务为简单多项式导函数的求解. 第二次作业:需要完成的任务为包含简单幂函数和简单正余弦函数的导函数的求解. 第三次作业:需要完成的任务为包含简单幂函数和 ...
- OO第一单元作业总结之初识面向对象
第一个单元的三次作业均为求导,循序渐进的让我们掌握如何构造类和方法,让整个代码是面向对象的设计而不是面向过程的设计.如果第一次作业和第二次作业你只是简单的对过程着手架构类,到了第三次作业就会变得格外麻 ...
随机推荐
- 执行Python程序的两种方式
目录 交互式(了解) 命令行式(了解) Python执行程序的三个阶段(掌握) 交互式(了解) 交互式环境下,敲完一条命令按下enter键马上能看到结果,调试程序方便.程序无法永久保存,关掉cmd窗口 ...
- 网络协议 终章 - GTP 协议:复杂的移动网络
前面都是讲电脑上网的情景,今天我们就来认识下使用最多的移动网络上网场景. 移动网络的发展历程 你一定知道手机上网有 2G.3G.4G 的说法,究竟这都是什么意思呢?有一个通俗的说法就是 ...
- .NET Core IdentityServer4实战-开篇介绍与规划
一.开篇寄语 由于假期的无聊,我决定了一个非常有挑战性的活动,也就是在年假给大家带来一个基于OAuth 2.0的身份授权框架,它就是 IdentityServer4 ,如果没有意外的话,一定可以顺利的 ...
- Java异常处理最佳实践及陷阱防范
前言 不管在我们的工作还是生活中,总会出现各种“错误”,各种突发的“异常”.无论我们做了多少准备,多少测试,这些异常总会在某个时间点出现,如果处理不当或是不及时,往往还会导致其他新的问题出现.所以我们 ...
- cocos creator主程入门教程(四)—— 网络通信
五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 前面已经介绍怎样加载资源.管理弹窗.开发一个网络游戏,难免要处理网络通信.有几点问题需要注意: 1.服务 ...
- JDK1.8-Java虚拟机运行时数据区域和HotSpot虚拟机的内存模型
目录 介绍 官方文档规定的运行时数据区域 程序计数器 Java虚拟机栈 本地方法栈 虚拟机栈和本地方法栈溢出 Java堆 演示堆内存溢出 方法区 运行时常量池 演示方法区溢出 HotSpot虚拟机的内 ...
- Axios发送AJAX请求
目录 Axios 特征 axios提供主要三种发起请求的方式 方式一:直接axios实例直接call方式 方式二:通过axios实例提供的不同http请求方式的方法 方式三:其实是从第二种方式中单独提 ...
- ArcGIS对SLD样式的支持
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.ArcGISWMS服务对SLD的支持 在完成用geoserver的w ...
- java.lang.UnsatisfiedLinkError:dlopen failed: “**/*/arm/*.so” has unexpected e_machine: 3
转载请标明出处,维权必究:https://www.cnblogs.com/tangZH/p/10458448.html 今天在做APP的时候使用so库,可结果一加载so库的时候便发生了这个莫名其妙的错 ...
- Maven 基本的认识
Maven 基本的认识 1. 什么是Maven? 在平时开发中,经常遇到某个jar包,我在代码层已经Import 和@Automation了,编译器还是提醒你某个jar包找不到,往往这时来个mvn i ...