OO课程第一次作业表达式求导

目录

方法介绍

面向对象

三次作业遇到的BUG

互测感想

自我评价

 我使用的方法简介:

1.预备知识

dfs深度优先的搜索

2.为什么要选择这个方法

1.设计简单:不会涉及到对象之间复杂的交互,而交互就容易带来问题

2.非常可靠:这是一种广泛使用的语法分析方法,可以相信它的拓展能力

3.先举一个例子

$x*x+x*x$ 求导

3.1向下求导

先从后向前找到第一个$+$

分解为$x * x$与$x * x$

左式从后向前找到第一个$*$分解为$x$与$x$

右式从后向前找到第一个$*$分解为$x$与$x$

左式的左边执行求导发现是基本项$x$求导为$1$

同理左式的右边,右式的左边,右式的右边也被求导

3.2向上合并

左式乘法合并就是$x * 1 + 1 * x$

右式乘法合并就是$x * 1 + 1 * x$

整个式子合并就是左式加右式

4.基本的架构思路:

1.整个函数叫$parse$的话。分解出左式右式后执行 $parse(左式)$,$prase(右式)$ 并根据中间的符号合并

2.我们能执行到找乘法的for的已经先把所有的加减法都去除了,能执行到找乘法的$for$之后的已经先把所有的乘除法都去除了,还能执行的只有基本情况了比如$1$, $x$, $sin(x)$。但我实际上实现的时候是先判别的这样可以减少分类的压力

3.为了简单起见我向上合并的项只有一种类型$Term$,它的核心是$private Map<String, BigInteger>$

 关于面向对象

类图

耦合度

class  OCavg   WMC
Main 5.444444444444445 49.0
ParsePare 1.9166666666666667 23.0
StringHelper 2.3076923076923075 30.0
Term 2.935483870967742 91.0
Tester 3.6666666666666665 11.0
Total   204.0
Average 3.0 40.8

质量分析

我理解的OO技术更接近于使用高内聚低耦合进行对于代码细节,质量上的提高,不是简单的类之间去传递信息就叫OO了。但是在我这方面做的不是很好,写出的并不是理想的规范化的程序。尤其是我的Term为了化简有大量的if形成了很大的WMC,Main由于我的设计原因,相当于集成了原本六个类的功能WMC也不小。代码应当有大量重构,比如Main还是应当分解,这样便于测试与维护,Term内的化简部分重构则比较困难了。

使用的对象创建模式

我的ParsePare其实就用到了工厂模式。它本来是一个括号解析器。它能够正向也可以反向的进行解析,可以一次插入一个字符也可以一次解析完一个字符串。我通过它的构造函数传入的参数区别了这几个情况,能方便的生产需要的方法。

三次作业遇到的BUG

第二次作业

1.没有考虑其它空字符:垂直制表符等

2.出现了空对象:在修改化简部分时有一部分特判空与特判指数的代码位置交换了,而特判指数的代码又不支持特判空

3.指数范围特判的处理:求导之后,我会重新解析一次以期简化,但他们复用了同一段代码,-100次方求导是-101次方,抛出异常。

第三次作业

1.关于加减WF判断错误:对于加法解析我会尽量去除加号(维护首项,项首的使用机会)。第三次作业没有理解之前设计的意图,给乘法解析增加了使用机会。

2.解析函数:由于sin里只能是项而我把()视为了恒等函数一起处理了,所以()里不是项就会抛异常。

 

互测感想

其实就是把指导书上所有的特殊情况进行组合,并合成一些比较长的式子层次比较深的式子,就足以卡出很多bug了

自我评价

最开始选择这个架构的主要原因是我很熟悉,并且我相信科学库里也是这么实现的。加上我上学期选修了java程序设计基础自以为面向对象写的还可以了,以为可以试试在实际的使用OO技术。但直到最后才觉得连门都没摸到。自己的思路被之前见过的递归下降的代码限制太深了(我并没有见过它的工程代码)。其实这个做法和课程一般的做法区别并不大,无非就是两个解析的方式不同。其实弄到最后就是课程组推荐的做法,事实上我的代码相当于把表达式项呀什么的都集成到Main中了,由于已经分解成函数了,和再分成那几个类差不多了,而向上合并只用Term表示也没毛病。

 

posted @ 2020-03-18 21:25  woafrnraetns  阅读(147)  评论(0编辑  收藏  举报