BUAA-OO-第一单元总结

一、程序结构分析

1.hw1

UML类图如下:

在这里插入图片描述
在设计代码架构时,我将Expr,Number(分别为表达式类,数字字母类)继承Factor接口来表示2种因子,然后设置Term类表示项。Lexer类和Parser类是出于使用递归下降法,与训练中给的做法类似;Polynomial类用于表示多项式,这个类为最后将表达式转化为字符串输出而服务。Simplify类则用于输入预处理。

2.hw2

UML类图如下:


在第二次作业中我新增了Func类用于表示自定义函数,Input类用于输入预处理(对自定义函数进行字符串替换),Exp类用于表示指数函数,Mono类则表示单项式,用于辅助多项式类进行计算。但整体架构没有发生太大变化。

3.hw3

UML类图如下:

在这里插入图片描述
本次作业我只新增了Dx类(求导因子类),通过继承Factor接口来表示求导因子因子。至于自定义函数调用,由于我在预处理时使用的是字符串替换,因此不需要修改即可满足要求。

总体而言,我的代码的整体架构在三次作业的迭代中没有发生太大变化。具体的优缺点分析如下:

1.优点

  • 将解析和计算解耦,分成两部分去设计,逻辑上比较清晰,代码可扩展性也较好。
  • 利用Factor接口将各种因子统一化管理,便于解析和计算时表示。
  • 创建了两个类用于对输入进行预处理以及对最后输出的字符串进行处理,为解析和计算提供了方便。

2.缺点

  • 第一次作业在优化的时候,由于我是优先输出系数为正的项,所以对于最先输出的项我忘了也要进行进一步的化简(如系数为0,1,-1这种情况),这导致我第一次作业强测中有一个点的性能分没有拿满。
  • 在递归生成最后输出的多项式时,时间复杂度比较高。
  • 第二、三次作业没有将exp()化简到最短。

度量分析

  • 方法复杂度

    在我所有的方法中尤以多项式类的toString方法最为复杂,主要是因为我把从多项式转化为字符串这一步几乎全部放在了这一个方法中。这确实是我当时在设计的时候忽略的一点(因为全放在一起比较省脑子)。
  • 类复杂度
    在这里插入图片描述
    如上图,由于我在对输入进行预处理时采用的是字符串替换的方法,因此Input类的复杂度较高。而多项式类由于其中的toString方法比较复杂,因此该类的复杂度也比较高。然后其他类大体上实现了比较高的内聚,之间的耦合度也相对较低。

二、架构设计体验

第一单元的三次作业是一个迭代的过程。第一次作业是化简表达式,其中表达式由项组成,项由因子组成,这个逻辑在之后的两次作业中都没有变,所以我的代码的主体框架也基本在第一次作业时就形成了,即按照表达式->因子->项的层次逐层进行解析,之后将表达式转化为多项式进行输出。

第二次作业新增了指数函数、自定义函数及多层括号。由于我使用的是递归下降法,因此多层括号的问题本来就可以解决。所以我只添加了指数函数类和自定义函数类来达到新增的要求。

第三次作业放宽了自定义函数的函数表达式的限制,同时加入求导算子。我也是只新增了求导算子类即可满足需求。至此,我的代码的整体结构最终完成。

至于新的迭代场景,我想到的是增加sin,cos函数。那么在这种迭代场景之下,我通过新增三角函数类,同时对原有的单项式、多项式类进行一些更改,即可实现新增的需求。

三、bug分析

在这三次作业中我的代码均未被测出bug(包括强测和互测)。与此同时我在第二次作业的互测中成功hack了别人两次,这两次都是通过评测机发现他们的代码存在bug。但我也将一些同学的代码下载到了本地进行查看,并根据他们的代码架构提交了一些针对性的测试样例。

四、优化分析

在第一次作业中,我通过对系数为0,1,-1的情况进行特判,合并同类项,以及优先输出系数为正的项来进行优化,并且在数学上证明了经过这种优化后可使输出达到最短。

而在第二次以及第三次作业中,我采用了把exp的指数乘到其括号里的方法,以及通过判断exp括号中是否是表达式因子(即是否含有+,-,*)来去掉在不必要情况下的多余的一层括号。其余与第一次作业相同。当然,这种优化方法在某些情况下无法达到输出最短(但是相比于提取公因式而言实现难度要低很多)。

由于我的优化逻辑并不复杂,所以在实现时能够保证代码的正确性。但是由于我对许多情况进行了特判,因此代码的简洁性受到了一定的影响。目前我想到的解决方法是可以将一些具有相同点的特殊情况进行合并从而使代码变得更加简洁。

五、心得体会

  • 在像第一单元这种逐步迭代的过程中,一个良好的、清晰的架构无疑会减轻之后的工作量。所以在第一次开始构建代码架构时就应该考虑一下将来可能的新增情况,确保代码的可扩展性良好。否则的话在出现了新的要求之后,可能会因为之前的架构不够好而不得不重构代码,工作量也随之剧增。
  • 在遇到一些比较复杂和困难的问题时,和同学一起讨论思路确实有助于发现解决问题的更好方法。例如在本单元的第一次研讨课中,我通过和小组内的其他同学进行讨论,找到了处理指数函数的一个新的角度,而在这之前我一直纠结于第一次作业的方法能不能继续用于指数函数。所以我觉得思维的碰撞确实能够产生意想不到的好结果。
  • OOpre课程还是很有用的,无论是面向对象思维的初步认识还是java语法的介绍,我觉得都对于第一单元的作业有比较大的帮助,至少做起来不是一头雾水。
  • 深克隆和浅克隆也是一个很值得注意的地方(我在这个地方卡了很久才找出来原因)。

六、未来方向

其实我觉得现在这样就已经挺好了,不过要想提高难度的话,往年的sin,cos是一个不错的选择。

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值