OO第一单元总结

OO第一单元作业总结

一、前言

  开学四周,不知不觉已经做了三次OO作业。事实上,每一次作业对我来说都是很大的挑战,需要花费大量的时间和精力来学习。

  虽然学得很艰苦,但最后还是连滚带爬地完成了。(好惨一人)

二、基于度量分析程序结构

(1)第一次作业

 类图:

《OO第一单元总结》

分析:第一次我写了三个类,Derivation类是负责构建一个整体的流程框架,输入、处理、求导、输出。Term类管理表达式的项,主要包含系数coe和指数index两个属性,Dealstr主要负责字符串合法性的判断和进行求导前一些简单的处理。此次作业我并没有很深刻地理解类之间的关系,只是凭感觉写了这三个部分,本质上还是面向过程的思想。

复杂度分析表:

i)Method metrics

《OO第一单元总结》

 ii)Class metrics

《OO第一单元总结》

 分析:求导方法复杂度很高,因为提取指数和系数的过程也在此方法内,由于indexOf()的特点以及指数和系数有省略的可能,此方法分了很多种情况,级联了许多ifelse语句,把各种情况用近似于枚举法的方式罗列出来,复杂度较高。

(2)第二次作业

类图:

《OO第一单元总结》

分析:本次作业我对Term类和Dealstr类进行了较大的改动。首先是在Term类中增加了sinindex和cosindex这两个属性,用来存储正弦函数和余弦函数因子的阶数。同时,由于本次作业增加了因子之间相乘的形式,所以我在Dealstr类中新增了一个系数相乘的方法calculate,用来把所有的项都化成“系数*x(阶数)*sin(x)(阶数)*cos(x)(阶数)”这一统一格式。并且对输入处理的正则表达式进行了改动。

复杂度分析表:

i)Method metrics

《OO第一单元总结》

 ii)Class metrics 

《OO第一单元总结》

分析:第二次作业我把求导方法devide拆分成了几个小部分,针对每一类因子进行求导操作,降低了方法的复杂度。但同时由于输入的形式变得更为复杂,所以judge方法的复杂度有所增加。

(3)第三次作业

类图:

《OO第一单元总结》

分析:第三次作业我利用了第二次作业的基本求导方法,在其基础上增添了判断嵌套以及递归求导的表过程。基本的正则与第二次相同,在判断输入的过程中,先匹配最基础(即无嵌套)的因子,此因子应符合第二次作业的正则表达式,然后这一层嵌套去掉,逐层判断。求导方法为递归求导,整体的思路是,先按照加减项将表达式分成若干项,再按照乘号将其分成若干因子,对各个因子进行求导。同时需要处理嵌套因子,当因子有嵌套时,将外层嵌套去掉,对内层函数求导,本质上就是自然的数学的求导方法。

复杂度分析表:

i)Method metrics

 《OO第一单元总结》

 ii)Class metrics

《OO第一单元总结》

分析:由于第三次作业基本上没有改动地沿用了第二次作业的内容,所以judge方法的复杂度仍旧是5,在递归求导的过程中,我将函数分层,layer方法由于有比较多的判断语句,ev(G)值较高。nested方法是最外层的递归求导方法,复杂度较高。

三、分析自己程序的bug

(1) 第一次作业

    在第一次作业的互测中,我被hack了17次,颇为惨烈,是因为我真的有很多bug。

  1. 在判断不合法的空格时,漏考虑了x^+   3和x^-    4这类指数的数字与符号之间带有空格的情况,导致对WRONG FORMAT的数据识别失败。
  2. 在判断不合法的空格时,用[+-]{2}\\s+这样的形式匹配,漏考虑了+  +  1这类常数中含有空格,并且项与常数符号之间存在空格的情况,导致对WRONG FORMAT的数据识别失败。
  3. 对正则表达式理解不够深入,[+-]?[+-]?连续使用,使其误匹配了两项之间没有任何符号的情况。例如,1231*x1231*x这个数据,我就会输出1231。同时,由于这个问题,当出现一个长度很长并且格式有误的数据时,就会爆栈。在bug修复的过程中,我将[+-]?[+-]?改为了[+-][+-]?,并且判断第一项前是否有符号,没有的话就增加一个’+’号,这样就修复了这个bug。
  4. 处理输出时,进行优化,如果某项的系数为0,则不输出。但是由于存在常数求导结果为0的情况,所以进行了特判输出,但是特判的条件存在漏洞,当情况为合并两项后产生的系数为零的一项,就会没有输出,导致bug。

 (2)第二次作业

    第二次作业的情况更不容乐观,在强测中,我有很多数据点都没通过,导致强测分只有48分。究其原因,追悔莫及,是因为我慌乱地写第二次作业,没有及时修复第一次作业的bug,致使第二次作业仍旧存在同样的bug。这次就没有第一次那么幸运能通过全部的强测点了,而是挂掉了许多点。同时,第二次作业产生了一些新的bug,在互测中,我被hack了28次,十分惨烈。除了第一次作业中出现的bug以外,我又产生了以下这些新的bug。

  1. 由于这次作业出现了因子相乘的情况,我在处理表达式的时候,没有考虑到 “*-” 这种情况,使表达式在这个’-‘号处将各因子误判成项从而分开,导致错误的结果。
  2. 由于这次作业中,第一个因子为1或-1时可以省略,写成+或-开头的形式,所以可能会出现三个符号相连的情况,而我在拆分表达式的时候并未考虑这种情况的变化,导致bug。

(3)第三次作业

    第三次作业在互测中被hack了8次,绝大多数是运行时错误的bug。这些bug是递归时产生的,难以控制的bug,属于设计层面的问题。这也是由于我面向对象编程的思想不够成熟,才产生了这样的bug。同时还有输出处理的错误,输出表达式的格式不对,有format error。

四、发现别人程序bug所采用的策略

    由于自己的精力有限,现在还没有进行对拍器等很自动化的寻找bug的方法的学习,仍旧是采取肉眼debug的方式,针对被测程序的代码设计结构来构造测试用例。在前两次作业中,这种方法还算有效,毕竟大家绝大部分是在输入合法性判断上有问题,虽然要对着7个人的代码看,但是总能找到一些小漏洞。第三次作业,课程组限制了WRONG FORMAT数据的提交,并且由于优化输出的程度不同,用人眼的办法已经很难找出程序的bug,并且手动输入的话,需要在七个窗口输入数据,效率实在是太低。不过我还是利用深层嵌套,长表达式和神出鬼没的’-‘号刀到了几个人。这些hack含有一定的运气成分。我在互测环节的活跃度不是很高,主要是别人刀我。

五、Applying Creational Pattern

    第一次作业完全没有理解多项式的产生特点,只是机械地产生类。第二次作业和第三次作业之间,我突然对数据之间的关系有了进一步的理解。虽然由于实践经验的缺乏仍旧没有写出很好的面向对象的程序,但是逐渐理解了这种思想的内涵。希望在今后的作业中能够有更好的应用创造模式。

六、心得体会

    正如老师在课堂上说的,OO课程是昆仑课程,走的很艰难,很缓慢,但是你在昆仑山上走下来后,在平原上走路就游刃有余了。虽然压力很大,但是我必须要坚持。写第三次作业的时候,我的电脑在星期一下午突然坏了,我本来十分绝望想要放弃,后来还是坚持下来,借别人的电脑,熬通宵,从头开始写。忍受着精神和肉体的双重折磨。不是想卖惨,而是激励自己,这么难的处境你都挺过来了,还有什么困难是你克服不了的呢?只要肯下功夫,肯花时间,不懒惰,同时善于求助,我想,即使菜鸡如我,拼尽全力也能及格吧,当然希望立的这个flag不要倒。

点赞