OO第一单元--表达式求导

第一次作业——简单表达式求导

本次作业类图如下

由于是第一次作业,还没有很好地体会到面向对象的思想,加之每一个项都具有固定的格式,因此只引入了Item类。主要处理方法为对于输入表达式进行一系列预处理,然后通过split进行项的切分。当读入一个项时对项的系数和指数进行解析并存储到每个对象中。求导过程由于均有固定格式,因此只使用了简单的求导方法也即可以实现。在最后的化简部分,使用了Treemap来合并同类项,并按照系数从大到小的顺序进行输出(这样可以保证存在正项和负项时正项始终在前)。最后的强测性能分为满分,但这次作业还是主要使用了面向过程的思想。

第二次作业——复杂表达式求导

本次作业类图如下

第二次作业相较于第一次作业,引入了格式判断部分,同时项的种类也变得更为繁多了。因此本次作业在第一次作业的基础上做了大量的修改。首先是将格式判断和表达式解析合并为一块,使用了正则表达式进行解析,其中正则项以及判断表达式类型的方法均置于Regex类中,且均为静态方法,便于管理使用。对于整个正则表达式而言,主要的流程为:①整体表达式match判断,若判断为否,则输出WF;否则进行下一步②按照项对于表达式进行切分③按照因子对于各项进行切分。在初期的设想是通过工厂模式对于因子进行处理,后面发现其实每个项都包含四个系数:①常数项的大小②指数项的指数③cos项的指数④sin项的指数,因此在搭建完框架后并没有完全按照框架进行求导运算,而还是主要对于项作为基本单元进行求导运算。最后的化简部分主要解决了四个系数均相等的项的合并、sin^2和cos^2类型的合并,最终发现还是有部分sin和cos的可合并情况没有考虑到。本次作业整体而言有了一些面向对象的思维在内,包括引入了factor抽象类,引入了简单工厂模式等等,但在具体实施的过程中图方便还是主要使用到了面向过程的思想。

第三次作业——嵌套表达式求导

本次作业类图如下

第三次作业在第二次作业的基础上引入了更为复杂的格式判断(对于空白正确性的判断),以及引入了嵌套的表达式格式。在初期思考的过程中一直没有明确的思路,通过参考讨论区各位同学的思路,最后决定以预处理最外层括号的方式进行判断切分。主要原理使用了递归的思想,对于每一层表达式,先将最外层括号进行预处理,同时简单修改Regex类的正则项,使得正则项可以简单地判断当前层表达式的正确性,在判断了本层表达式正确性之后,通过栈和递归的思想进一步判断表达式项内的表达式正确性,直至递归结束。在格式判断部分使用了一个函数对其进行整体判断。在判断结束后,正确的表达式进行下一步的切分。这次的切分方式基本上与第二次作业的切分无异,除了在对于嵌套表达式因子以及三角函数因子中使用到了递归的思想,在生成的过程中递归调用生成子因子。最后求导部分,整体思路为表达式求导=各项求导之和,各项求导=各因子求导之积,因子求导对应各自的求导形式。同时引入了Derivation接口,保证所有的表达式,项,因子都能够实现求导的功能,同时使用工厂模式统一调度并创建对象,最终实现了求导的功能。由于本次整体化简较为繁杂,因此本次的化简主要都是基于各层的处理,比如对于某些特殊情况求导可以直接返回"0"等情况,不过由于部分疏忽,也引入了其它的BUG。

BUG分析

对于第一次作业来说:由于使用的方式较为简单,因此没有遇到过BUG

对于第二次作业来说:本次作业在写的过程中遇到了一些BUG,但大多为读题不仔细导致,整体实现方法上并无明显BUG,而由于粗心导致的BUG也均在中测阶段解决。

对于第三次作业来说:本次由于任务较为麻烦,因此由于考虑不周引入了两类主要BUG:

①对于格式判断的BUG,由于本次对于空格的WF判断采用了穷举的方式,在判断没有空格的WF后删除了所有的空格。但这也导致了一些其他的错误在这个过程中消弭,导致了sin(-   x)这类的格式错误没有判断出来

②由于在表达式求导过程中有运行时的化简,同时对于表达式括号的处理出现了一些问题,因此最终导致了两类问题的发生,其一是表达式的括号位置不对,或者是没有加上应该加上的括号。其二就是对于某些输出为0的情况输出了()这样的错误形式。

 

查找BUG策略

对于互测阶段的BUG查找方式,主要使用了Python中的os和sympy两个库,对房间内所有同学进行整体对拍。而测试数据的选用大多都为手动构造,其中主要涉及到的就是一些复杂表达式、嵌套表达式、以及一些边界情况。通过整体对拍,在发现他们的BUG的同时也找到了自己存在的BUG。

 

对比和心得体会

这三次作业主要都是围绕着表达式求导这一核心任务展开的,而由于第一次没有考虑太多后期拓展的问题,因此第二次的作业基本上都是重写。而第二次考虑一下拓展问题,因此第三次作业基本上是在第二次作业上进行的修改,因此考虑良好的拓展性是必要的环节。其次就是对于面向对象思想的一种体会,可以看到,这三次作业中,我的整体思路主要也是由面向过程思想转向面向对象思想,我感觉这两者思考模式的主要不同点就在于对于整个任务的分解。对于面向过程思想来说,完成一个任务实际上就是划分好一个流程的过程;而对于面向对象思想来说,完成一个任务更像是一种对于类和对象的组织。但总体来说,我还是觉得这两种思想对于编程来说都有可取之处,而面向对象思想在使用时也不应该局限于其本身,而是合理的选用取舍,对于一些问题的处理可以以面向过程的思想来处理,但整体架构保持面向对象的完整性即可。

 

猜你喜欢

转载自www.cnblogs.com/1806lay/p/12537124.html
今日推荐