BUAA OO UNIT1 多项式求导单元总结

UNIT 1 多项式求导

Homework 1

  • score:100

  • 代码增量

    • 本次作业较为简单,只需建立形如\(ax^p\)的单项式类和形如\(\sum a_ix_x^{p_1}\)的多项式类即可

      • 多项式类使用TreeMap实现,value为单项式,key为单项式的指数
      • 使用merge更新多项式,重写toString即可
    • 读入部分只需编写正则表达式读取每一项,再用第二层正则表达式读取项中的x、常数、指数即可

      • 读入x,则指数+1
      • 读入**p,则指数+p-1
    • 输出部分将正项、负项分别转成String,然后将正项拼在负项之前,去除开头的+号

  • Bug&Fix

    • Bug: None
    • Fix: Pass
  • metrics

Method ev(G) Rank Line Rank
wk.Re.ngrp() 1.0 2 28 1
wk.Atom.str() 5.0 1 17 2
wk.Main.main(String[]) 1.0 2 9 3
wk.Poly.toString() 1.0 2 8 4
wk.Poly.df() 1.0 2 7 5
wk.Atom.df() 1.0 2 5 6
wk.Atom.equals(Atom) 1.0 2 3 10

image

image

  • 类图
    image

Homework 2

  • score: 84.59

  • 代码增量

    • 递归下降读入表达式
      • 虽然用栈也能实现同样的功能,但为了可扩展性还是选择了递归下降法
      • 但实际上递归下降在java上并不易于实现,递归下降法最终也没有达到预期的可扩展性
    • 多态类存储表达式
      • 建立抽象类Fun,实现Comparable、Cloneable接口,声明必须包含的求导、化简、修改等方法
      • 各函数的具体类继承Fun,其中,常量、sin、cos、x的实现较为简单
      • 注意到系数和指数分别可看成累加和连乘的简写形式,所以只需定义累加和连乘类,使用map存储每一个元素,key为元素,value为系数或指数
      • 由于涉及递归,我不太信任hashcode的安全性,因此使用treemap实现,compareTo方法为递归比较。
  • 性能优化

    • 删除0系数、0指数成分
    • sum、prod类自带合并同类项
    • 不支持因式分解
  • Bug&Fix

    • Bug: 由于其他课程压力过大,加上因为重构耗费了两倍的时间,没有时间仔细测试本次作业,导致出现丢失符号的bug,被hack19次。
    • Fix:关闭导致此问题的性能优化代码,将return null改为return 0多项式。
  • metrics

BUG方法 圈复杂度 rank 代码长度 rank
Prod.trim() 6.0 1 25 2
Sum.trim() 4.0 3 1 5
Main.main() 3.0 8 17 5
其他方法 ev(G) Rank Line Rank
Sum.toString() 3.0 8 27 1
Prod.compareTo(Fun) 5.0 2 22 3
Sum.compareTo(Fun) 5.0 2 22 4
Prod.push(Fun,BigInteger) 3.0 8 16 7
Sum.push(Fun,BigInteger) 3.0 8 15 8
Re.exp() 4.0 4 14 11

image

image

  • 类图
    image

Homework 3

  • score:99.56

  • 代码增量

    • sin、cos函数嵌套

      • sin、cos内部增加child属性记录括号中的因子,略微修改即可
    • WRONG FORMAT

      • 增加Err函数,化简和求导均返回自身,toString方法返回“WRONG FORMAT!”
      • 由于多正负号、过大的指数、sin、cos内部嵌套多项式等多种情况不合法,故原先的递归下降代码需重写
    • 性能优化

      • 总体上仍然是很多低垂的果实没有拾取,考虑到时间分配以及最终成绩,这看来是明智之举
      • 支持脱壳:累加类、连乘类中若仅有一个元素,则返回该元素,删除原类
      • 不支持因式分解
  • Bug&Fix

    • Bug: None
    • Fix: Pass
  • Method Metrics
    method_metrics

  • Class Metrics

  • Code Lines

  • Method Lines

  • chart
    image

image

  • 类图
    image

image

互测与hack

  • 没有自动评测机,互测就无从谈起
    • 第一次作业由于自动评测机没搭好,也不想在这上面花太多时间,所以就随便测了测自动编译能不能用,意外hack了一个人。
  • 乱搞压标算
    • 其实大家的整体结构相差并不大,存在结构性问题的几率较小,更多是因为嵌套和控制分支太多造成隐藏bug,因此随机测试效果会比较好。
    • 第二次作业我的数据基本上为手工构造,基本思路是先构造连续规则的数据,然后向其中乱搞地加入一些符号。然后16次提交成功hack24次,当然有我在B屋的原因。
    • 第三次作业我把这种乱搞过程自动化,就形成了我的数据生成器,9次提交成功14次。
  • 空白字符很重要
    • 强测不含空白字符导致一部分实现得并不好的同学也来到了A屋,我屋里有三份代码本地测试时通过率不足50%,我甚至不得不替三位同学修复bug才能使评测继续进行。
    • 这个过程中,我发现他们实现递归下降的方式极为复杂,存在多重嵌套调用和多重控制流,这些代码中或是出现笔误,或是有情况未考虑,使得他们把正确输入错判为WF
  • 丢失字符
    • 后续还发现有位同学在第三次作业出现了我第二次作业中的错误——丢失字符,推测可能是第三次作业新加入了优化代码,没有充分测试导致。

总结

  • Java编程技巧

    • 三元表达式真香
    • 函数式编程真香
    • 正则表达式及其难用
  • 自动评测机

    • 别人的轮子就是最好的轮子

      自动编译部分使用Github WinGrep项目搜索源文件和package。实际运行时发现bug,上午反馈给开发者,晚上就收到修复。

    • 命令行也有好ui

      实时进度条、评测结果统计表等等特性并不难实现,却能显著提高评测机可用性

    • 乱搞压标算——论好的数据生成器

      第三次作业中我的数据生成方案是

      1. 给每种符号编号
      2. 生成只含x和常数对应编号的序列
      3. 向其中随机洒入括号、sin、cos函数,注意括号匹配
      4. 输出时随机加空白符

      这个生成器成功找到了我和几位朋友平均每人5个bug,且速度极快O(n),与输出同复杂度

  • 时间管理

    • 重构代码是灾难
posted @ 2021-03-25 20:35  fallqs  阅读(105)  评论(0编辑  收藏  举报