OO第一单元总结

目录
  • 设计思路
    • homework1
    • homework2
    • homework3
  • 程序度量
    • 结构分析
    • 代码行数分析
    • 复杂度分析
  • Bug
  • 应用对象创建模式
  • 心得体会



设计思路

第一单元作业的主要任务为函数的求导,从作业1到作业3难度依次增加。作业1的任务为简单多项式的求导,给出了多项式的形式化表述,并且不要求进行格式检查;作业2新增加了因子的概念,一个表达式由多个项相加,一个项由多个因子相乘,而每个因子可以是幂函数、正余弦函数或者常数,并且要求格式检查;作业3进一步针对三角函数增加了复合函数求导的要求,三角函数内部可以复合表达式。


homework1

因为表达式为简单多项式,我们只需要用 ArrayList 等可变长的结构去存储每一项的信息即可。每一项都是一个幂函数(常数也可以看成幂函数),需要记录系数指数,在项这个类中实现求导、toString 等方法,然后表达式类的实现实际上就是各个项的累加。

对于输入数据的提取,我们可以利用形式化表述构建正则表达式,按项拆分后提取信息即可。

考虑优化输出长度,我们可以用 HashMap 来记录项的信息,key 为幂函数指数,value 为幂函数系数,这样可以很方便地进行合并同类项的操作。


homework2

同样地,表达式是由多个项相加而成,而且每个项都有固定的因子乘积:(coe)*(x**powX)*(sin**powSin)*(cos**powCos),所以大体的结构在 homework1 的基础上可以不用修改多少,我们主要修改项这个类的内容就可以了(另外这里项的求导会得到一个表达式类,要增添表达式合并的操作)。


homework3

第三次作业增加了复合操作,可以看出原来的结构处理不了这种情况,所以只好重构。我构建了一个 factor 接口,接口要求实现求导和 toString 方法,然后建立了Sin, Cos, Power, Multis, Adds 五个类,分别记录正弦、余弦、幂函数、多项乘积、多项和的信息(工厂模式)。 Sin 和 Cos 记录了 sin/cos(fac)**pow 这样的信息,其中 fac 是一个 factor 类,pow 是指数;Power 记录了指数信息(本次作业不要求幂函数的复合);Multis 和 Adds 分别实现了一个 factor 的 ArrayList。这样的话,表达式实际上就是一个 Adds 类。通过对每个类实现求导和 toString 方法,就可以很好地完成任务。

由于复合导致不能仅仅用正则表达式处理输入信息(因子和表达式相互嵌套),我们可以考虑对输入进行递归处理。我的处理方法是:在处理当前表达式时,用栈将所有最外层括号找出来,然后把这对括号包括里面的内容替换为一个 subStr(比如说"#"),然后将里面内容保存;预处理完之后,对形式化表述稍作修改,我们就可以利用正则表达式提取信息(因为预处理之后不再有嵌套);在提取信息时,每遇到一个 subStr,就拿一个刚才存储的内容出来,对这个内容(其实也是一个表达式)递归表达式处理,处理结果合并到当前表达式处理之中。

在这种思路下作业3有很多细节问题,需要多多调试。




程序度量

仅针对作业3,进行结构分析、代码行数分析和复杂度分析。


结构分析

作业3的程序结构(UML图):


代码行数分析

作业3代码行数(LOC):

OO第一单元总结_第1张图片

可以看到总共行数为593行。


复杂度分析

作业3类复杂度分析:

OO第一单元总结_第2张图片

其中 OCavg(Average operation complexity) 表示每个类的非抽象方法的平均循环复杂度,WMC(Weighted method complexity) 表示每个类各个方法的总循环复杂度。




Bug

第一次作业:处理时一边迭代一边删除元素导致了ConcurrentModificationException异常。

第二次作业:未发现。

第三次作业

  1. 输出时出现了 x*+(...) 这样的错误(表达式因子前面没有正负号);
  2. 输出时出现了 () 这样的错误(空括号);

可以看出,第三次作业主要的bug都集中在最后的输出上面,根据我的分析,因为我们要执行 toString 时,对于各个类还要考虑其他类的输出结果(因为很多类的属性中都会嵌套 factor ),所以很多细节问题需要多多debug。


找别人的bug主要就是用的自己的自动化测试啦。




应用对象创建模式

从设计思路部分可以体现。




心得体会

通过本单元的学习,我大致掌握了java这种OO语言的基本使用方法,并且熟练掌握了工厂模式、正则表达式、接口、继承等等知识。

在自动化测试方面,我的自动化测试还有很大的不足之处,具体表现为:

  1. 数据生成几乎是随机性的数据,没有针对性和覆盖性;
  2. 没有考虑到 sympy 可以正常识别 x*+(...) 这种实际错误的格式,导致没能检查出作业3的这个bug(强测错的4个点全是这个问题),经过思考,其实可以把输出结果再用java代码判断一次格式是否正确;
  3. 自动化测试过程中,只有WA才会报错(也就是python标准输出计算结果与java输出计算结果不一致时),而java编译运行过程中的异常不会导致评测机报错退出,所以作业1的异常bug和作业3的 () bug(实际上python读取时会有异常)没能检查出来。

之后还是要好好改进自己的评测机。

你可能感兴趣的:(OO第一单元总结)