BUAA_OO 第一单元作业总结

张艺轩-22373207 2024-03-22 00:07:04

一.hw1

第一次作业需要完成的任务为:读入一个包含加、减、乘、乘方以及括号(其中括号的深度至多为 1 层)的单变量表达式,输出恒等变形展开所有括号后的表达式。

UML

1.1架构分析

第一次作业的架构较为简单,但也为后面的部分埋下了隐患。

1.1.1预处理

预处理部分分为输入部分,deletespace()功能为删去输入字符串的空格和'\t',deal()主要解决连续加减号的问题,使其变为一个“+”或“-”,standard()部分主要功能是处理数字前的正负号,如果“+”直接不读入,“-”就变为(-1)*或者+(-1)*,需要根据数字的位置进行特判。

1.1.2表达式解析

这部分主要是表达式树的建立,主要分为Expr,Term和Factor类,其中Factor为接口,包含有表达式Expr类,未知数Unknown类(第一次作业只含有x)和Number类,将表达式逐步拆分为因子的过程。

1.1.3去括号

去括号部分沿用了助教推荐的递归下降法,于parser中实现parserExpr,parserTerm,parserFactor。

1.1.4项的合并

在全部计算完并输出后,我发现同指数的项都单独罗列了出来,导致输出结果很长很长,非常不便于阅读和比对,因此我把这部分放到了Expr的两个Print()函数中,在合并完后直接进行输出。第一次作业我采用哈希列的方式来存储每个项的系数和指数。

其中Print2()就是根据指数为1,-1,0,>0,<0,来分别输出,过于冗长这里不进行展示。到这里总算解决了合并同类项的问题,得到了相对简洁的结果。

1.2度量分析 

1.2.1代码度量分析

我的三次作业都将输出直接写在了Expr中,导致Expr类代码过多,应该考虑迁出来单独输出为好。Mainclass过长的原因主要是我将deletespace(),deal(),standard()函数都写在了Mainclass中,应该更加精简一点。

 1.2.2类复杂度分析

代码量最多的就是Expr和MainClass类,这两个类由于进行输出和字符串标准化处理,导致非常屎山,当时时间紧没做出很好的优化,方法层面,因为我是多个if分条件打印,所以导致两个print函数也很长,面向过程表现得太明显了,后续争取逐渐向面向对象靠拢。

二.hw2

第二次作业中需要完成的任务为:读入一系列自定义函数的定义以及一个包含幂函数、指数函数、自定义函数调用的表达式,输出恒等变形展开所有括号后的表达式。、

UML

2.1架构分析 

第二次需要加入指数函数和自定义函数,同时未知数也由一个x变为x,y,z,复杂度飙升。第一次时我完全没有考虑到exp的嵌套问题,导致我的代码遇到exp(exp())时直接算为1了,也因此没有通过第二次中测的weak5,第二次作业直接寄掉了。第三周重新改写加入exp的嵌套后,如上图UML所示,新增了Function,Trans,Monomial,Exponent四大类。

由于第一次作业的系数和指数是用Hashmap存储的,但是新增了指数函数,原来的方法不再适用,我加入了Monomial类,coefficient仍为系数,index为x的指数,Exponent存指数函数,在Exponent中实现指数函数的存储。而由于Expr先被拆分为Term,所以Trans类的作用就是将Term转换为Monomial存储。Function部分则是自定义函数类型,存储函数名,形参,函数内容。此外,Parser类中还实现了将形参替换为实参的操作。

2.2 度量分析

2.2.1代码度量分析

第二次作业仍然是Expr和MainClass太长了,没办法只能在这里继续添加exp和自定义函数了,这就导致架构变得越来越糟,应该在一开始就把这两部分简化的,时间太紧了没做出很好的优化。 

2.2.2 类复杂度分析

新增部分的都还可以,仍然是历史遗留问题,第二章作业一定要在第一次就努力把架构简化,避免出现现在的惨状。 

三.hw3

第三次作业中需要完成的任务为:读入一系列自定义函数的定义以及一个包含幂函数、指数函数、自定义函数调用、求导算子的表达式,输出恒等变形展开所有括号后的表达式。

UML

 

3.1架构分析

通过第二次作业的改动,第三次作业的要求变得简单了许多,只需要加入求导因子dx,要注意求导公式的写法,在这里我花费了一些时间去研究。

3.2度量分析

由于第三次作业较第二次改动不大,所以不在这里赘述了,只是增加了求导类Dx。

 

四.架构可扩展性

我认为我的架构可以较为容易的向其中加入新的函数,比如可以加入对数函数,只需要在Monomial中新增存储底数的地方,其他的我认为与指数函数并没有太大区别。但对数函数要求导可能就涉及到分母的问题,目前没有太好的解决方案,毕竟第一章作业也是避开了除法这项操作。

针对上学期的三角函数,我认为可以直接新建一个三角类,然后按照Monomial的方式存入就行了,但是要注意求导时sincos的转换,在求导公式里列出来就好了。

五.Debug心得(de自己的和de他人的)

5.1hw1

hw1的中强测通过的还是比较顺利的,没有正确性出现问题的数据点,因此没有太多感想。在互测时,因为我当初下载的jdk1.8版本,无法把他人的代码下载跑评测机,所以并未发现其他人的bug,只是按照评测机提交了几个自己认为可能出现错误的数据点,hack不成就以得到基础分为目的了,并没有做深入的hack

5.2hw2

hw2的中测当时出现了严重问题,最初只能通过三个测试点,疯狂de后仍有两个测试点未通过,其中一个测试点自定义函数的替换问题,当里边含有指数时没完全替换过来,为此我修改了Parser类里边形参和实参的传递部分,成功通过测试点,但经过不断询问后,发现weak5测试点涉及到了exp的嵌套,这就是前边提到的隐患,因为在写代码的时候忽略了这个问题,发现时已经不足3小时,最后疯狂添加也没有通过测试点,不幸挂掉第二次作业。同时也未能进入互测。

5.3hw3

修完exp的嵌套问题后,并加入了求导部分,但是中测部分还是出现了各种各样的错误,检查时发现求导的计算逻辑出现了错误,修复后也是通过了中测,但同样倒在了强测的恶魔数据点面前,第三次作业也未能进入互测。

同时第二次作业和第三次作业都出现了共同的错误,就是exp里究竟要套几层括号的问题,在中测阶段也是报错了,我采取了比较简单无脑的方式,就是在最外层都套了两层括号,勉强解决了这个问题。

总结来讲,bug主要出在存储Monomial和计算exp上,此外还有多层嵌套会tle的情况。

六.优化

我的优化主要是对输出进行的优化,代码本身比较复杂,没有很好的做到面向对象编程,很多情况都是拉出啦单独处理的,这导致代码过于繁琐,第二章会进行优化简化的。

七.心得体会

一谈到体会,突然有说不完的话。在大二上的时候我天真的以为c++oopre是“或”的关系,忽视了oopreoo学习中的重要战略地位,导致第一次作业时完全麻爪,甚至都不知道要干什么,后续也是磕磕绊绊才完成了作业。最初的目标是争取进入补给站,oo第一章对我的挑战实在是太大了,完全不知道是什么,该怎么写,这也导致了我第二次作业时没及时发现exp的嵌套,草草处理的重大失误。Oopre对于学习oo实在是太重要了。而且oo的作业,互测安排也十分紧凑,对于我来说总有一种时间不够用和时空错乱的感觉,每次都是周六下午匆匆忙忙完成中测,对于我的挑战很大。第一章的成绩虽然不是很理想,但是对于基础这么差的开头来说也算差强人意。不过通过第一章的作业我也了解了面向对象编程的奥妙,争取第二章的电梯作业里可以多拿几分,争取多进几次互测,体验一下被疯狂hack的感觉。

 

...全文
58 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

301

社区成员

发帖
与我相关
我的任务
社区描述
2023年北航面向对象设计与构造
学习 高校
社区管理员
  • YannaZhang
  • CajZella
  • C_ecelia
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧