OO第一单元总结
概述
OO第一单元的主题是多项式求导,在寒假作业熟悉了java的基本语法以及正则表达式的用法后,让我们结合面向对象的思想来解决一些实际问题。第一次作业是只含幂函数以及常数的简单多项式,第二次加入了三角函数,第三次加入了嵌套因子以及表达式因子,三次作业的难度由浅入深,在编程思想上也逐渐实现从面向过程到面向对象的过渡。
第一次作业
思路: 总的来说第一次作业就是一个字符串的处理。先通过正则来判断输入的数据是否非法,这里的坑点是如果直接用一个大正则来判断可能会由于回溯而爆栈(如500个-x),故我们不得不采用逐项判断的方式,因为首项的特殊性(前面可以带加减号也可以不带),因此可以优先匹配加减,之后就可以把首项也同化成一般项处理。之后求导时的思路是开两个Arraylist,一个存指数一个存系数,用一个字符串记录结果即可,在提取系数指数这一步时因为已经保证了表达式必定合法,因此可以做一些预处理(如删除多余空格等)来简化我们提取信息的难度。总的来说我认为用这种设计思路一层层往下结构还是比较清晰的。
分析:可以看到关于信息提取的extract方法以及计算部分的cal方法的复杂度都过高,因为自己的惰性后来也没有去优化,毫无疑问这是一种不良的设计方式。 写第一次作业时因为自己太菜下意识的只分了一个类,不管是系数指数的提取构建还是求导以及输出全都杂糅在这个类里面非常的不科学,并没有充分体现面向对象的思想,如果优化的话将信息提取和求导过程分开应该是个不错的选择,或者将这个大的poly作为父类,下面再开子类。
**debug: ** 本次作业优化时非常脑残的把+0去掉了导致一旦有+0*x之类的情况就会出错,自己太过粗心考虑不周,可见在思维的严谨性上还有待提高。互测时用了一些大家可能会犯的共性问题,如空白符以及爆栈问题去测试,效果还是挺不错的,同时由于这次代码比较简单因此也可以直接看代码找bug
第二次作业
思路:第二次作业本质上和第一次作业区别不大,只是新增了三角函数的功能,因此我选择了直接在第一次作业的基础上增加功能(因为自己的惰性并没有仔细思考助教对优化结构的劝告,以至于在第三次作业痛不欲生),改写了每一项的正则同时增加了三角函数的求导功能,很多技巧也都沿用了第一次的设计,总体结构与第一次相同。
分析:有UML类图可以看出完全是继承第一次结构,只有两个类,可以说这样的结构设计师非常的不合理了。其实现在回过头来看这里就应该对因子进行分类了,新开一个factor类,分为常数,幂函数以及三角函数,对每种因子都实现求导接口,同时建立item类以及exp类,分别实现它们的求导方法如此一来结构就会清晰许多,也会大大减轻第三次作业代码重构的工作量,同时采用这种结构系统的鲁棒性和可扩展性必定会大大提升。
debug:这次作业吃了符号判断的大亏。我起初的算法是先匹配首项,匹配到了就把它replace为空格,然后再匹配一般项,匹配到了就replace为空格,如果最后只剩空格那么就认为匹配成功,其实这个算法有一个严重的bug就是会将一个项的前后内容联系起来如+sin+x(x)它就会认为这是对的。。。。后来经过与同学的交流发现可以现在整个字符串后面加一个正负号然后以项符号的整体为一个单元逐项匹配。这次的互测技巧除了用自己在写程序时积攒的数据,就是看他们的正则了,因为随着代码量的增长想去看他们的全部程序对我这种咸鱼已经不太现实了。
第三次作业
思路:因为第二次作业没有思考结构的优化导致这次作业几乎成了火葬场,这次作业的难点就在于嵌套因子和表达式因子可以无限嵌套,通过单纯的正则来判断和提取信息已经行不通。我最初的想法是写一个FSM,就后来经过一个下午的实践发现状态之多问题之复杂让状态机的构建非常困难,于是更改了思路,按照助教的给的提示通过构建表达式树来解决问题。开Node构造结点,开tree用于建树,构建树的时候对一些因子做了特殊处理:基于三角符号比较特殊见到三角函数直接建成一颗小树,见到带指数的三角函数先以^为根节点建树,再建立相应的三角函数指数,个人认为这种处理方式比较灵活,对于嵌套因子和表达式因子均是在建树的时候使用递归处理。树建立完毕后,在树上做递归求导即可。
分析:本次作业由于时间原因自己太懒导致我并没有像大多数同学一样建立factor,item,exp类分别处理,而是直接在建树和求导的过程中杂糅了这些功能,所以说可读性和可扩展性都不是很好,结构比较混乱,做优化的话把每个因子的求导法则和正则判断规则都用接口实现,再在做树的时候调用毫无疑问会清晰很多。
debug:因本次作业的代码量非常大而且禁止使用Wrong Format数据给互测带来了相当大的难度,几乎唯一的手段就是手写自动评测机来测试大家的程序。
总结###
我觉得我目前还没有真正的理解面向对象的思想,很多思维仍然是面向过程的模式,很多时候都是为了用面向对象而用面向对象。
三次作业下来和大佬一对比发现每次我的代码架构都比较差,可扩展性都不是很高,如果本单元还有第四次作业的话我可能又要重构。。。。对于继承和接口的使用也没有很强的意识,而这些东西在将来实际开发的工作中是非常重要的,希望在接下来的电梯和出租车作业中能加强对面向对象设计的理解与运用
OO这门课毫无疑问的增加了我的抗压能力和编程设计能力,很多东西看起来简单但实际去做的时候总会发现很多的问题,罗马不是一天建成的,我会紧跟课程组的要求继续探索面向对象这做高山,我相信它在将来会成为我宝贵的财富。