BUAA_OO第一单元总结

第一单元作业总结

【注】以下所列出的思路、架构可能与实际提交作业有所区别,由于时间有限,实际提交代码的部分内容尚未完善。

1.第一次作业——单变量多项式的括号展开

1.1 设计思路

第一次作业作为第一单元的开山之作,难度适中,主要任务是对括号展开问题建立初步的认知,建立初版架构。

首先,这次作业涉及的对象有:

  • 带符号整数:可能含有符号与前导零
  • 因子
    • 变量因子
      • 幂函数:分为一般形式与省略形式,
    • 常数因子:包含一个带符号整数
    • 表达式因子:由小括号包裹且可能带指数
  • 项:若干因子的乘积,第一个因子前可能额外带有符号
  • 表达式:若干项的加减,第一项之前可能额外带有符号

其次,我的总体处理流程为:
读入表达式 → 处理第一个项 → 处理第一个因子 … → 处理第二个项 … → 处理最后一个项

为实现上述流程,我计划定义五大类,其中含有一个Main类和一个抽象类,如图所示。

Data类是数据类型的抽象类,其中的String以字符串形式存取待处理的对象。
mapHashmap<Int, BigInt>类型,存取处理后的内容,Int类型的键为指数,BigInt类型的值为系数。
process为各对象的处理方法,通过调用该方法进入parse函数。
parseTermparseFac分别获得下一个项及下一个因子。
处理因子时,首先通过type函数判断该因子的类型,0为常数,1为幂函数,2为不带指数的表达式因子,3为含指数的表达式因子。
之后通过一系列的dealCase方法对因子进行处理,将结果存至map中。
由于此次作业运算不是很复杂,故没有另外定义运算类,而是将运算过程融合进了处理方法。
在处理字符串时,我使用了正则表达式的方法。
由于本次作业格式较为简洁,通过正则表达式进行匹配非常高效,但是十分不利于扩展,因此也只有这次使用了正则。
处理完毕后,所有内容都储存在了Poly类的map中,通过print方法输出最终结果。

1.2 代码度量分析

整体来看,类的功能以及类之间的关系比较清晰。
但由于将字符串处理和运算融合进了各类中,类的圈复杂度还是很高的。
尤其是parseTermprint方法明显过于冗长,独自一人承担了太多,导致复杂度飙红。

1.3 Bug

由于第一次作业难度适中,在强测与互测时都没有被发现bug,且也没有发现别人的bug。
但互测屋内有同学被找出了bug,主要与符号处理有关。对于-+-1这样的情况,很多同学直接采取字符串替换的方法,虽然可以达到目标,但不够灵活,在面对复杂情况时可能出现问题。

1.4 测试

构造测试用例的方法和作业思路类似,首先将因子分为若干类分别构造,再随机选取若干种类型的因子构成项,再把若干项随机组合为表达式。在构造数据时需要注意以下几点:

  • 表达式不能嵌套,因此在构建表达式因子时需要避免递归
  • 数字部分需要考设计前导0
  • 项与因子前需要考虑设计额外的符号

1.5 小结

通过这次作业,成功建立起初步的架构,为后续的迭代开发提供基础。同时训练了面向对象的思维。但类的复杂程度仍然较高,在后续设计时应加以注意。

2.第二次作业——加入三角函数、自定义函数与求和函数

2.1 设计思路

本次作业的数据复杂度明显增加,难度也随之加大,主要表现为:

  • 新增三角函数:需要重新设计结果的存取与表示方法
  • 新增自定义函数:需要额外设计自定义函数类
  • 新增求和函数:需要额外设计求和函数类

处理流程为:

自定义函数预处理 → 读入表达式 → 处理表达式(与第一次作业相同)

类图为:

对于第一次作业中原有的类,只是在功能上作了扩充,总体结构为改变。
对于数据对象,新增了Sum类和Function类。它们与TermFactor等类的地位类似,只是在具体实现细节上有所不同。
此次新增了运算接口,AddMul类通过接受两个列表分别进行加法和乘法运算。
这次作业,最重大的更新是新增了Tuple类,用以存储项的结构。
一个项可由四部分组成:系数(含符号)、幂函数的指数、sin函数类、cos函数类。
对于前两者,使用整数类型表示即可。对于后两种,尽管本次作业只允许三角函数内出现常数因子与幂函数,但为了充分考虑可扩展性,决定使用ArrayList,其中的每一项存取的都是一个Poly类型的数据,这意味着三角函数内可支持任意类型的数据,实现了递归结构。
进行字符串解析时,不再使用正则表达式,而是使用类似于文法分析的逐字符处理。

2.2 代码度量分析

本次代码复杂度依然很高。
具体查看每一个方法,发现依然是parseTermparseFactor方法承担了太多工作,
以及新增的addFunequalX方法繁琐冗杂。
尤其是对于Function类,含有大量相似的代码,这些需要通过简化设计进行优化。

2.3 Bug

同样,本次作业在测试中没有发现bug。但我在查看他人的代码时发现了3处bug,它们都与三角函数的优化有关。
例如,试图提取sin内的符号但处理错误、试图化简平方和但处理错误等等。
由此可见,这些同学在处理表达式时未被发现问题,反而是在优化性能时未注意到相关细节。
因此,不要一味地追求性能分而忽略了最基本的正确性,否则是得不偿失。

2.4 测试

用例构造思路与第一次作业类似。对于新加入的自定义函数,可在满足约束条件的前提下生成表达式,其中的自变量随机从x,y,z中选择。
对于求和函数,首先随机生成上下界,再生成求和表达式,并把其中的randint(0,n)x更换为i

3.第三次作业——引入更多嵌套规则

3.1 设计思路

第三次作业没有引入新的对象,但对可嵌套性进行了扩充。
由于在第二次作业时,我的架构已能支持各因子之间的嵌套,因此设计部分几乎没有进行改动。
针对输出括号的要求,修改了PolytoString方法。当表达式只含有一个因子时不输出括号,其余情况输出括号。
此外,针对性能优化完善了三角函数的化简方法。

3.2 代码度量分析

通过分析代码的复杂度可知,此次作业较上次作业有一定程度的上升,而这主要是因为上述化简方法。
由于三角函数的嵌套关系比较复杂,在判断平方和等条件时需要较多的判断条件,分支语句较多,逻辑较为复杂。

3.3 Bug

很不幸,此次作业我被测出了bug,在输出括号的判断条件上出现了问题,导致sin((-x))会输出为sin(-x),而这主要是没有认真审题导致的,充分说明了仔细阅读指导书的重要意义,教训深刻。
此次我也发现了别人的bug,同样也出现在三角函数的化简上,而且与我第二次作业发现的bug非常相似。可见三角函数的化简不是一项简单的任务,任何一处细节的缺失都有可能造成毁灭性的打击。

3.4 测试:

测试用例的构造思路基本与第二次作业一致,只是放开了嵌套的限制。
由于我的架构可以支持任意组合的任意嵌套(递归除外),因此生成用例的约束很少,只需注意在定义函数时不要调用自身即可。

4.迭代设计感悟

从第一次作业到第三次作业,我基本上是按照迭代的思路进行设计。大致框架为:
第一次作业:只含有Data类及其继承类,运用正则表达式解析字符串,采取递归下降方法展开表达式。
第二次作业:扩充Data类,增加Sum类与Function类,引入运算接口及其实现类,自定义Tuple类作为项的结构。
第三次作业:完善三角函数的化简,更改括号输出方法。
可见,最大的跨越是在第一次到第二次作业。又由于第一次作业已经打好了基础,整体框架脉络比较清晰。
经过分析,我在第一单元的迭代设计有以下优缺点:

  • 优势
    • 架构基本上依次顺延,没有进行较大范围的重构。第一次作业已经采用递归下降法对字符串进行处理,后续的作业虽然加入了更多复杂的概念,但整体处理方法能够继续使用,奠定了良好的基础。
    • 加入新的类时,尽量统一它们与前期工作的关系。例如,Sum类和Function类仍然继承Data类,它们的属性和方法与其他数据类相似,只是在处理细节上有自己的特点,没有必要另辟蹊径。
    • 可以根据需求进行小范围的更新而无需大量修改。例如,加入三角函数后,虽然数据的表示方式产生了很大的变动,但通过引入Tuple类直接解决了此问题,原有的类只需将属性map更换为ArrayList即可。
  • 教训
    • 第一次作业为图方便采用了正则表达式,后续作业不得不抛弃此做法而另外设计文法分析。如果从一开始就采用此方法,会减少很多工作量。
    • 第一次作业没有定义运算接口,后续作业由于复杂度陡然增加新设计了运算类。应该从第一次作业开始就采取此做法,这样不仅可以降低代码的复杂度,还能使类的功能职责更加清晰,在debug时也能更快地定位问题点。
    • 前几次作业没有追求性能,不能将三角函数最简化,后续才加入相关功能,导致工作量进一步加大。

5. 收获与反思

第一单元的任务已经接近尾声,回顾前三周的工作,自己有很多收获,也有很多思考。

  • 首先,这三次作业我都成功完成了指导书列出的基本要求,实现了复杂表达式的展开,没有出现毫无头绪、望题发呆的情况,建立了信心。
  • 通过这些任务,我进一步加深了对面向对象设计的认识,实现了从面向过程到面向对象的思维转变。
  • 对Java语言的一些特性有了更全面的了解。
  • 由于没有仔细弄清指导书的要求,在最后一次作业中出现了低级错误。因为不掌握面向对象设计而出错,尚能理解,但因为这种原因导致失分,不可原谅。对于一些人来说,不能完成一项任务往往不是因为能力不足,而是因为在没有完全理解甲方的需求时就开工了。无论是现阶段完成课内的作业,还是今后参加工作,知道自己要做什么都是最重要的。
posted @ 2022-03-23 19:02  DreamWave  阅读(62)  评论(1编辑  收藏  举报