北航OO课程第一次作业总结

北航OO课程第一次作业总结

度量分析

类图以及代码规模

(以下类图由plantuml手动创建)在这里插入图片描述

在这里插入图片描述

​ 如类图所示,在我的设计中将各个组成表达式的成分打包成了expr这个package,其中包含Expr(表达式),Term(项),Index(指数函数),Unkown(幂函数),Function(自定义函数),Number(常数)这些具体的成分,以及Factor(因子)这一通过接口实现的抽象层次。另外,我将Calc(计算)作为各类计算的一个总和整理起来,其中包含了化简所需要的表达式的相加,相乘,项的相加,相乘,各类因子的计算等等。将解析等操作放在了Package包之外。

​ 我认为我的设计有以下几个优点:

​ 1.通过接口Factor实现了统一的管理,让各种因子有了行为上的共性,比如derive(求导)方法,clone(克隆)方法等等。让各类其他操作有一个相同抽象层次的管理结构。

​ 2.将计算整合成一个Calc类,将其中相互调用的方法放在同一个类中,更加直观。比如合并同类项中,表达式的相加需要调用数字,指数等相加,有了这个类,就使得这些相互调用更加方便。

​ 缺点:

​ 我通过对比其他同学的代码,反思自己的代码,认为我应该建立一个Poly(基本项)类,将每个只包含系数,指数,幂函数的项统一管理为基本项类。这样能够使化简更加方便,同时能够降低性能开销。比如基本项只含有限个因子,不含表达式,减少了表达式树的复杂程度。在我自己的代码中,在实现化简后,需要额外的findIndex,findNumber等方法来找到化简后的基本项的属性,增大了性能开销。

内聚耦合分析

在这里插入图片描述

​ 在类的度量中,由于Calc是计算所需所以OCavg值较高,同时包含较多的计算方法,还有着较高的WMC的值。如果如上文所说,我创建一个基本项类,并将系数等作为它的属性,计算的逻辑会更加简单,Calc的耦合程度以及复杂度都将下降。
在这里插入图片描述

​ 而在方法的度量中(以上仅截取了部分CogC较高的方法),我发现在计算因子的乘法中,由于涉及到了因子类型的判断,以及由判断而进入的不同类型的乘法处理造成了CogC值的较高。而这种计算是可以通过基本项的建立进行简化的。另外在simplify的方法中,由于合并同类项涉及到容器中因子的去除和增加,这些判断和调用造成了复杂的增加,同样可以优化。

三次作业架构的设计体验以及BUG

第一次作业

​ 第一次作业的逻辑比较简单,只包含幂函数因子和常数因子,并且不包含括号的嵌套。所以在第一次作业中只需要做到建立Factor的抽象层次,并写好Expr,Term等基本类的方法,通过完善递归下降的解析方法来建立树即可。

​ 主要的难点:

​ 1.理解递归下降的逻辑,判断好token的各种情况,并进行相应的处理。

​ 2.去括号中的toPoly方法的实现。由于我们知道在进行标准化之后,表达式中不再含有括号,也就意味着整个表达式树只有三层,即expr,term,factor三层。我的逻辑是化简后返回一个term的Arraylist,在Expr类中,是现将它的各个项进行toPoly然后将这些项进行相加后返回,而在Term类中,我将因子乘了个1或-1,再进行返回,处理了项的正负号的问题。

​ 3.化简simplify的实现。表达式的化简就是合并同类项,项的化简就是合并同类因子。

​ 由于第一次作业逻辑比较简单,然后含有training的参考,所以我和互测时都没怎么出bug。

第二次作业

​ 这次作业增加了自定义函数和指数函数,以及括号嵌套。不仅增加了两个因子,还需要我们对化简等其他方法进行修改添加。

​ 主要的难点:

​ 1.自定义函数的处理。我感觉我身边的大多数人采用了字符串替换的处理逻辑,将表达式中的形参替换为实参,而事实证明这种方法应该是比较简单的一种。而我采用的是比较复杂的一种,会产生比较大的性能开销和更多的代码量。我的主要逻辑是在函数定义时使用Parse类直接将表达式建立一个树,然后在输入实参时,即解析最终的表达式时将自定义函数进行深拷贝,并将实参替换形参。这样无疑在克隆时会产生额外开销,并且在替换时需要进行遍历,也会产生性能开销。这应该算是我踩过的一个坑吧。

​ 2.指数函数的化简。指数函数是可以将乘方乘在指数上的,但是这里会产生一些问题,就是字符串的长度问题。当然这里设计的性能分是那些大佬的竞争点了,我只是无脑的将乘方化简然后将合并同类项加一些逻辑判断罢了。

​ 主要的bug:除了一些手残bug和眼瞎bug,我主要出现了以下bug

​ 1.引用问题。在某个逻辑中,我发现没有涉及到的对象的某个值突然发生了变化,在找了半天之后,我发现我定义了一个新对象,然后对它进行了修改。而实际上,我所定义的对象只是对于一个已有实例进行了另一个引用。所以对这个实例,我进行了莫名其妙的修改。当然这属于逻辑上的疏漏,究其原因还是我自己对于引用的机制不太熟悉。

​ 2.性能问题。在强测之后,我发现我的cpu和内存爆了。原因就是循环次数太多和创建对象太多。而循环次数是由于多次乘方嵌套,对于这个bug我的解决方法就是加特判,对于单因子的表达式优先进行指数修改,并及时化简。而内存爆了的问题,我只能说如果我使用的是字符串处理自定义函数,将会大大节省性能开销。

第三次作业

​ 第三次作业就简单了不少,只是增加了求导的方法。而在这次的代码中,我没有新建一个求导因子类,而是直接在其他因子中增加了相应的求导方法,并且按照课程组的提示,构建了不同的求导法则。

​ 在这次迭代中,我犯了很多弱智的错误,导致了一些bug,而唯一一个逻辑上的错误是对于深拷贝的判断。即在逻辑上应该对对象进行深拷贝,之后还要用它操作之前的某些属性,但是在设计时没有想到这一点,导致在求导过程中,将不应该变的属性进行了修改。

心得体会

​ 之所以没有单独的写debug和hack的板块,是因为我这次debug全靠自己构建数据,这是我这一整次作业最大的败笔。因为自己构建的数据太简单,会导致一些很弱智的bug测不出来,平白在强测中丢了很多分,甚至没进互测。所以在下一次作业中,我肯定会进行全方位进行测试,包括单元测试和自己构建数据,评测机等。毕竟这次的教训太大了。另外,我认为我这次的另一个败笔就是在设计过程中没有考虑性能问题。这就导致了性能出现bug之后,由于重构需要将整个代码重写,给我造成了很大麻烦。在下次作业中我一定要在开始就注意及时化简,减少循环次数,减少重构。同时,另一个我认为需要做到的是,减少方法的复杂的,也就是简化一个方法的功能,降低方法之间的耦合。

未来方向

​ 我觉得课程安排已经比较合理了,真的使我的能力有了比较大的提升。

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
北航数值分析大作业第一题要求在CSDN上找到关于数值分析的学习资料。首先,CSDN是一个广受欢迎的技术社区,提供了大量的技术文章、教程和代码示例。因此,在CSDN上找到数值分析的学习资料并不困难。 首先,我可以通过CSDN的搜索功能,输入关键词“数值分析”来搜索相关的学习资料。搜索结果会显示一系列与数值分析相关的文章和教程。我可以根据内容的质量和适合自己的难度进行筛选。 其次,我可以查看CSDN中一些专栏或博客的数值分析分类。在这些专栏或博客中,经常会有数值分析方面的文章,可以从中获得更加系统和全面的学习资料。我可以关注一些高质量的专栏或博客,通过查询他们过往的文章,找到自己感兴趣的数值分析学习材料。 此外,CSDN还有一些论坛和问答社区,我可以在这些地方提问关于数值分析的问题,寻求其他技术人员的帮助和建议。这不仅可以加深自己对数值分析的理解,还可以扩展自己的网络,与更多的专业人士交流。 综上所述,北航数值分析大作业第一题要求在CSDN上找到关于数值分析的学习资料。通过利用CSDN的搜索功能,查找数值分析的相关文章和教程。同时,我还可以关注数值分析相关的专栏和博客,参与社区的讨论,获取更加全面和深入的学习资料。在这个过程中,也可以通过提问和交流,加深自己对数值分析的理解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值