BUAA_2023_OO第一单元总结

一、程序结构分析

1.1方法复杂度分析

1.2类复杂度分析

1.3类图:

Main:包含读入输入,删除空格,预处理,处理函数,处理求导因子,最终进入Lexer的字符串只需展开括号

Lexer:读入字符串,返回处理得出的因子以及Parser的控制符号受Parser驱动

Parser:依据Lexer返回的控制符号,递归处理Lexer返回的因子,能够驱动Lexer解析

Expr:储存Term串,以及有求导,toString,Expr、Term之间的运算方法

Term:储存整数,x、y、z的指数,sin里面的Expr串,cos里面的Expr串,作为最小的数据单元,还有求导、toString、比较同类项等方法

优点:结构清晰简单,类较少,易于书写

缺点:层次化不足,不够面向对象,每次迭代需要修改很多东西,还是面向过程式的解题

二、架构设计体验

第一次作业一开始上手,有指导书这么刻意的引导下,我自然而然的想到表达式、项、因子的层次化架构。但因为没有想出这种架构下应该如何输出与化简,最后用了表达式、项两层的架构。项中包含整数,x、y、z的指数,Lexer返回因子与控制符号,Parser统一返回Expr。这也是异常的好写。

第二次作业加入了自定义函数与三角函数。此时我尝试重构,因为我的第一次作业确实不好迭代开发。我一直构思新的架构直到星期六早上仍然没有完整的思路,最后为了完成第二次作业只能继续沿着第一次作业硬改。最后发现也其实很好改。最开始的时候通过字符串替换展开所有函数,此时自定义函数就不用再考虑了。只用处理三角函数,只需给Term类新加两个属性,ArrayList<Expr>sins,与ArrayList<Expr>coss就可以很好的存储,解析时也只是递归调用即可。

第三次作业增加了求导因子。我采用和处理自定义函数一样的方式,在最开始时和处理自定义函数一起处理了求导因子。之后就跟第二次作业一样处理即可。当然还需给Expr和Term增加求导的方法。

三、bug分析

第一单元作业总共出现了3个bug,前两个发现在第一次作业的互测中,第三个出现在第三次作业的强测与互测中。其实这些

第一个bug出在我对指数为0的因子的处理中。我是采用正则表达式匹配然后替换的方法,问题出现在匹配的不完备。当指数存在前导0时,我将只匹配到第一个0,然后将这部分替换成1,导致出现如将x**01替换成11的bug。最后的bug修复是通过判定0之后非数字才停止。

第二个bug出现在我对表达式因子左括号前的负号的处理中。我是当Lexer中读到左括号时,判定前个字符是否为负号,如果是,修改Lexer的一个属性为true,然后在Parser中读取这个属性,如果为true,就给parserFactor返回的Expr乘-1。但是我判断条件多了一个判断返回的Expr的大小是否为0,导致如果是-(0)+(1)这种情况的话前个表达式因子的负号会出现在下一个表达式因子中。最后的bug修复我删除了这个size的判断条件。这个判断条件也确实是没必要的,我也忘了当时我为什么加入这个判断条件。

第三个bug出现在我对函数替换中,对函数实参为求导因子的处理时,忽视了内部表达式中存在函数需要替换的情况。对于函数,求导的处理我是在解析表达式之前进行的。我在Main中写了两个函数delFun与delDer,作用分别是展开字符串中的函数与求导因子。delDer的原理是先parser传入的字符串,将这个字符串化成没有括号的表达式,从而便于Expr与Term的求导方法,而这个字符串是不能含有函数的。然而对函数实参的处理中我只写了delDer(string),从而导致了当string中含有函数时报错。而弱测中并无这个点,从而让我蒙混过关了。最后Bug修复也只用修改成delDer(delFun(string))就可以了。反思这个bug能存在的原因主要在于我没有对程序进行充分的测试。当时我只花了三个多小时写完第三次作业时我是十分高兴的,以至于修完弱测中的bug后就置之不理了。

四、分析他人程序bug的策略

我分析他人bug是通过阅读他人代码,但实践证明这种方法效率极低也很难让人有耐心看下去,三次互测中我只发现一个人的一个bug。

我以后或许会尝试搭建测评机,通过测评机测试他人程序bug。

五、心得体会

总的来说,这个单元的三次作业对于我对面向对象的理解只有一点帮助。当然,这其中有很多是我个人的问题,我尝试通过面向对象的方式解题,但难度摆在这以至于我并没有成功。我无奈只能采用过去的熟练的面向过程式的思维来解题,这从我作业的迭代开发可以很明显的看出,我将自定义函数因子、求导因子的处理视为一个个的模块,通过加入模块的方式解题,这很不面向对象。

我也想给课程组提一些建议,我们能否使用一些非常适合用面向对象的思想解的题作为作业,也即用面向过程式的思维是非常难处理的题目作为作业,而且两种思维解题的难度差异必须大到足以掩盖我们过去训练带来的面向过程式思维的熟练。

这三次作业是个反面例子,我试图面向对象但这让我束手无策,而面向过程反而让我得心应手。我这三次作业完全没有接口、继承等等这种面向对象的东西,除了仿照训练来的Lexer与Parser,让我体会到一些对象封装的妙处,以及Expr,Term类的方法封装在类中方便调用的好处外,我并没有实践更多的面向对象。

总之,期待后续的作业吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值