OO-2021 第一单元总结

一、程序结构与OO度量

第一次作业

(1)设计思路

数据结构:

  根据直觉和文法,按照表达式-项-因子的层次设计了数据结构。其中,<因子>存储形式为 类型-值,为后续增加新类型因子留下余地,<项>则是一个<因子>的ArrayList,而表达式则是<项>的ArrayList。

输入处理:

  因为本次作业没有错误的输入格式,因此对数据进行了预处理,清除所有空格、并将连续的+/-号合并为一个+/-号。

 

 

   构建了Parser类负责分析语法成分,按照层次构造分析的方法,并且根据层次进行调用。getExpression(), getTerm(), getFactor()分别对应了解析表达式、项和银子的方法。上一层语法层次会调用下一层。

计算化简与求导:

  本次作业的计算化简和求导的方法在三个数据结构类中分别实现,根据计算规则,因子间支持乘法multiply(), 而项之间则支持加法add()。由于只有一个表达式,表达式的运算和多个项之间运算并没有本质区别,因此没有实现表达式类的运算方法。此外,由于求导规则较为简单,也没有采用逐层调用的方式,而是在表达式和项一级就实现了功能,因子的求导方法并没有具体实现。

(2)类图

除了用于测试的主函数类test,有四个其他类:

Parser: 负责输入的语法成分分析,将结果存到设计好的数据结构中。

Expression:负责表达式的存储、化简和输出。 

Term: 负责项的存储、计算、化简、求导和输出。

Factor: 负责因子的存储、计算、求导和输出。

具体的属性、方法和类图如下:

 

 

 

 

(3)OO度量

类:

 

 

 方法:

 

 

 

 

第二次作业

(1)设计思路

数据结构:

  总体改动不大。对于新增的因子类型cos和sin, 只需要改变相应的type值即可。而对于带有括号的复合表达式,会被转化成不含括号的和上次作业一样的“简单表达式”。

      而由于括号的出现,因子、表达式、项的语法分析结果均需要用表达式类存储处理。

输入处理:

  最大的变化在于括号的出现,使得因子中可能嵌套表达式。因此本次作业参考了编译语法分析中的递归子程序法,对带括号的部分进行递归调用。如下图所示,getFactor()中会递归调用getExpression()。

 

 

 

计算化简与求导:

  第一次作业的计算化简和求导的方法在三个数据结构类中分别实现。而本次作业的计算化简更加复杂,因此单独实现了Cal类,通过重载实现各类型之间的乘法和加法。

     求导则依旧在三个类中通过调用下一层的求导方法实现。

     在求导与运算的过程中,会在计算前后调用化简方法,以期最后的结果长度最短。

(2)类图

除了用于测试的主函数类test,有五个其他类:

Cal: 实现了表达式、因子、项之间的乘法和加法。

Parser: 负责输入的语法成分分析,将结果存到设计好的数据结构中。增加了递归调用。

Expression:负责表达式的存储、化简和输出。 

Term: 负责项的存储、求导和输出。

Factor: 负责因子的存储、求导和输出。

 

(3)OO度量

类:

 

 方法:

 

 

 

 

 

 

第三次作业

(1)设计思路

数据结构:

  总体改动不大。因为sin和cos表达式括号中的内容不再固定为‘x’, 因此增加了因子的属性"str"来记录三角函数括号中的内容

 

输入处理:

  增加了格式检查的环节。先按照文法对输入进行了语法检查,再进行预处理,只需在原有的直接获取内容的分析方法中加入判定即可。由于作业并不考虑时间上的性能,采取了“多遍”的形式,没有将语法检查和分析一同进行。

 

计算化简与求导:

  除了在计算中保留sin和cos函数括号内的内容,并没有其他大的改动。

(2)类图

除了用于测试的主函数类test,有五个其他类:

Cal: 实现了表达式、因子、项之间的乘法和加法。

Parser: 负责输入的语法成分分析,将结果存到设计好的数据结构中。增加了语法检查。

Expression:负责表达式的存储、化简和输出。 

Term: 负责项的存储、求导和输出。

Factor: 负责因子的存储、求导和输出。

 

(3)OO度量

类:

 方法:

 

 

 

二、自己程序的BUG

第一次作业在强测和互测中出现了RuntimeError。

推测出现原因为Parser读取输入的循环终止条件有问题。

第二、三次作业互测和强测均未被发现bug。

 

三、互测发现的BUG

因为个人精力有限,只能关心自己的程序,并未参与互测。

 

四、重构

  由于第一次作业中就划分了层次,并为后续扩展留下了一定的空间,因此总体上改变并不是很大,唯一一次较大的重构是在第二次作业中:

  为了降低类的复杂度和耦合性,并提高可读性,将各个类间计算的方法从各个类中移到统一的Cal类中。这同时也方便了重载、测试等环节的进行。

  

五、心得体会

  首先,我收获了很多。通过这个单元的学习,我对面向对象思想有了较为深入的理解,并掌握了递归、正则表达式等工具的运用。

  但需要改进的地方也还有很多。由于个人原因,我对代码风格、互测等环节无暇顾及,好在后两次强测结果都是90+,还算不错。争取以后有机会深入参与互测,改进代码风格。

posted @ 2021-03-30 18:06  1506zzn  阅读(74)  评论(1)    收藏  举报