OO第一单元总结

前言

第一单元 OO 作业的主题是求导,从最简单的幂函数求导,到添加三角函数求导,再到最后添加嵌套规则。(对熬夜有了新体验,OO 作业比较适合晚上写,OO 博客也是一样 doge)

一、代码分析

分析将主要通过UML图,OCavg 和 WMC 三个方面来分析。

OCavg 代表类的方法的平均循环复杂度

WMC 代表类的方法的总循环复杂度

第一次作业

第一次作业总的来说很简单,只需要对幂函数进行求导,而且没有 WF 的判断需求,我直接上大正则匹配,同时尝试了一下面向对象的编程模式(虽然最后还是面向过程的更多一些)。

UML 类图

复杂度分析

总结

虽然想着的是面向对象,结果还是面向过程,这一点在 MainClass 充分体现了,所有的表达式拆分,求导完的组合都是在这个类中实现的,十分笨重。

不过在这次作业中,因子作为基本单位进行求导,再将求导结果通过特定规则合并奠定了我接下来几次实验的总体的设计方向;对输入内容,从表达式拆解到项,再从项拆解到因子,最后求导完再从因子一层层往上进行合并最后输出。

第二次作业

添加了三角函数,为了扩展性,我从比较多的地方留了空间,方便新内容的添加,不过对于接口实现这个方面在当时还不是很了解;仍然是通过正则表达式来分类,从表达式拆解为项,项拆解为因子的方法来存储每一个因子,再通过合并的方式传递求导结果。

UML 类图

复杂度分析

总结

这个单元作业写得挺丢人的,自己没有理解好接口和类的区别,有的部分的实现,很明显太累赘了,比如 Factor 这个类还自己实现了一个接口 Function,然后这个接口和 Factor 这个类基本内容都是一致的,因为没有理解到接口可以直接管理实现了相同接口的类(找个地洞钻进去)。

在复杂度方面,Item 这个类需要兼顾 WF 的判断,拆解项为因子和因子的制造等多方面的内容,整个类很笨重,在扩展方面留下了隐患;同时我没有采用工厂模式,这个在扩展性方面比较差,在第三次作业针对这个方面进行了修改。

这次也是同样采用逐级拆分表达式为项,再拆分项为因子的办法,同时也考虑了对于第三次作业的扩展性,在表达式和项这两个类中都采用字符串加容器的管理方式,兼顾了合并同类项优化和扩展两个方面。

然后为了优化,专门建了一个优化的类,类似于打补丁的方式,对三角函数的化简进行了合并,然后不需要的时候删除掉就好了(嘿嘿)。

第三次作业

增加了嵌套因子,基本依托第二次作业开展的,然后从中分离出了一些方法,如 WF 的检查,因子对象的制造等,为了降低复杂度。

UML 类图

复杂度分析

总结

分解的层次可以这样理解:

  • Expression

    • Item

      • Factor
  • Factor 是一个接口,所有的因子都实现了这个接口,然后可以通过这个接口来调用所有的因子,就是一种多态的实现方法。

  • Expression 和 Item 类中都采用容器的管理方式,管理的对象主要分为两类,一类是求导前的集合,一类是求导后的集合,方便优化等多方面的管理。

这次作业相较于上次作业其实是一个扩展的过程,这个从 UML 图中也可看出来,添加了 Expr 表达式因子这个类,然后将 WF 的判断和因子的生成给分离出去,建造了 WrongFormatCheck 这个类和 Factory 这个工厂,将原本 Item 类中的东西分离出去;同时删除了上次的“优化补丁”,将优化融入到了整体中。所以整体的框架没有变化太多,第三次作业整体做起来还是挺快的,兼顾了优化和扩展性,比较多的时间花在了 debug 上(捂脸)。

分析下这次作业的内容,这次作业添加了嵌套因子和三角函数可嵌套这两个很伤的内容,主要是对正则表达式用户很不友好,所以为了能够使用正则表达式,我采用了先检查 WF,再通过预处理简化正则判断过程的方式来继续使用正则,出现 WF 的时候通过抛异常来终止程序。

其次工厂真是个好东西,如果还需要扩展的话,以后只要多个实现接口的类,添加个工厂制造方法,就可以比较容易就实现了。

这次的复杂度相较上次有一点点下降,整体的脉络也更加清晰了,但是类中的复杂度还是挺高的,主要是优化这个点,为了脱括号,拆因子,添加了挺多的内容。如果日后还需要扩展的话,或许将优化分离出来会有更强的扩展性。

二、Bug 与性能分析

Bug

自测:

在自测的时候发现了挺多 bug 的,主要是通过自己的测评机来发现的,主要问题一般为以下两个方面:

  1. 优化过度,该有的没了,比如第三次作业中的表达式因子的括号该不该脱;
  2. 对于对象的管理,一个对象有了多个管理者,这些管理者在调用和修改对象上出现了交叉,导致在一个管理者中对象被修改,在另一个管理者中其实不期望它被修改,修正办法就是不进行对象的直接管理权的赋值,而是通过先克隆,将克隆对象交予其他管理者。
  • 数据生成主要是用 python 自带的正则包,最后一次的生成主要通过概率递减的方式来生成嵌套因子,基本做到了数据的全面性,在测试中非 WF 数据的测试没有出错;同时通过一定算法检查了自己的优化效果,在优化方面也给了自己很大帮助。
公测与互测:

本人在三次中测和互测中都没有出现 bug,前两次强测也没有出现 bug,但在最后一次强测中出现了关于 WF 判断不完全的 bug。本人在正答数据方面都做了很充分的测试,没想到最后竟然在 WF 方面的疏忽给了这次作业一个不完美的结局。

以下直接贴我的 bug 修复文档,说明得很详细,也给自己提个醒。


性能

在第一次和第三次的强测中,我的性能分几乎是满分(除了第三次 WF 的点的性能分没拿到);然后第二次强测中,大佬们太花了,真的玩不过,性能分算是看得过去。

优化主要是从细节出发,从最基本的因子的优化,将优化完的因子交给项;项再优化,把优化完的项交给表达式;表达式进行一个循环的优化,因为是单线的优化,就是固定优化几个方面的内容,比如三角合并,比如括号脱掉,直到没有再能合并或者能够脱括号的,不用考虑 TLE 等问题(课下通过 java 内置函数对上百近千的数据进行过测试,也没有超过规定范围时间,所以比较放心)。

其实只要做好了整体框架和层次的建立,优化可以说是水到渠成的事情,从局部最优到整体最优,是一种贪心的思想。

三、互测

本人在互测中没有出现 bug,然后 hack 了挺多人的,每次 hack 数据点在两位数,只要是互测屋中有 bug 的都 hack 成功了。

  • 主要采用的方式就是,放进评测机,找到小于提交长度的关键数据上交,发现了大家的挺多问题的,从优化,到 WF 的判断,再到 TLE,主要找到的 bug 都是来自这三个方面。

  • 比较遗憾的一点是对于很大一部分同屋的同学,自己其实没有很认真读他们的代码,一方面是自己比较懒,另一方面是看了整体的 java 文件,觉得没有很好地分类的和有层次性的代码都过滤了。不过也有幸和几个大佬同屋过,阅读完他们的优化方案和层次觉得受益匪浅。

四、应用对象创建模式

这方面的收获主要来自于工厂模式(真香)。

第二次作业一结束,就开始研究了关于工厂模式部分的内容,在第三次作业中将工厂模式充分应用,其实工厂类应该还要继续划分为具体的工厂,但是没有下一次作业了,就图方便全写在一起了。

对于工厂模式的体会,就是无敌的扩展性,因为每当需要一个新的内容,只需要将工厂类下新建一个分支,不需要对原有代码有过多的修改,就能够很好地实现一个新功能。

五、心得体会

  • 测评机是个好东西,自己的测评机一开始设计就是扩展性和多应用场景的(曾经还一度想着商业化),在互测这方面节省了自己很多时间,十分感谢讨论区大佬们的建议,特别感谢qsy同学的“测评机”实现方法的介绍,不知道接下来的作业中还能不能用到测评机这样的好东西
上张图纪念一下(一家人就该整整齐齐)

  • 拿到作业的第一时间绝对不是直接开干,应该先倒杯水,打开 typora 开始“抄指导书”,先对指导书中的内容充分理解,其实指导书本身也在框架和优化上有很多可以暗示,我们应该对作业有个整体的认识,然后才是着手代码,先搭好框架,再完善细节,这是我三次作业的体验(然后每周二晚上我都一直在喝水)
  • 扩展性的保留将决定你接下来两三周好不好过,其实很感谢自己在第二周的时候考虑了挺多方面的内容的,第二周可以算是最难的一周,重构了两次,为了之后好添加新内容
  • 讨论区是个好东西,互联网是个好东西,自己很多细节上的处理,特别提名 x**2 -> x*x,都是来自讨论区同学们的经验,来自互联网上前辈们的 OO 总结,十分感谢
  • 多和他人交流和分享,我觉得这是一个互助的过程,在向别人讲解自己的框架的时候,自己的认知也就更加具体了,然后对于模糊的地方也更加确定了;然后别人的分享对你也是一种启发,第二次作业的两次重构就来自与某同学的交流,然后我二次重构的周四写了一天
  • 最后在接口,多态,模式,容器,字符串处理方面都有更加整体,立体的认识(挺好建议加大力度 doge,要是下次太难当我没说)

感谢助教和老师们在 OO 课程中的付出,辛苦啦!

OO 第一单元的更多相关文章

  1. OO第一单元作业总结

    oo第一单元的作业是对多项式的求导.下面就是对三次作业分别进行分析. 第一次作业 分析 第一次作业相对来讲比较简单,甚至不用面向对象的思想都能十分轻松的完成(实际上自己就没有使用),包含的内容只有常数 ...

  2. OO第一单元总结

    OO第一单元作业总结 一.前言 开学四周,不知不觉已经做了三次OO作业.事实上,每一次作业对我来说都是很大的挑战,需要花费大量的时间和精力来学习. 虽然学得很艰苦,但最后还是连滚带爬地完成了.(好惨一 ...

  3. OO第一单元优化博客

    OO第一单元优化博客 第一次作业: 合并同类项+提正系数项+优化系数指数0/1=满分 第二次作业: 初始想法 一开始是想以\(sin(x)​\)和\(cos(x)​\)的指数作为坐标,在图上画出来就可 ...

  4. 【OO学习】OO第一单元作业总结

    OO第一单元作业总结 在第一单元作业中,我们只做了一件事情:求导,对多项式求导,对带三角函数的表达式求导,对有括号嵌套的表达式求导.作业难度依次递增,让我们熟悉面向对象编程方法,开始从面向过程向面向对 ...

  5. OO第一单元(求导)单元总结

    OO第一单元(求导)单元总结 这是我们oo课程的第一个单元,也是意在让我们接触了解掌握oo思想的一个单元,这个单元的作业以求导为主题,从一开始的加减多项式求导再到最后的嵌套多项式求导,难度逐渐提高,编 ...

  6. 【作业1.0】OO第一单元作业总结

    OO第一单元作业已全部完成,为了使这一单元的作业能够收获更多一点,我回忆起我曾经在计算机组成课设中,经常我们会写一些实验报告,经常以此对实验内容反思总结.在我们开始下一单元的作业之前,我在此对OO第一 ...

  7. OO第一单元(前四周)作业总结

    OO第一单元(前四周)作业总结 OO第一单元(前四周)作业总结要求(第四次作业) 0.前言 本次博客针对的是本人学习Java的第一阶段的三次作业的作业总结 第一次作业的内容是:7-1 计算税率 (20 ...

  8. 北航OO第一单元作业总结(1.1~1.3)

    经过了三次作业之后,OO第一单元告一段落,作为一个蒟蒻,我初步了解了面向对象的编程思想,并将所学内容用于实践. 一.第一次作业 1.架构分析 本次作业需要完成的任务为简单多项式导函数的求解.表达式仅支 ...

  9. OO第一单元总结与反思

    OO第一单元总结与反思 目录 OO第一单元总结与反思 摘要 第一次作业 本次作业UML类图 本次作业度量分析 第二次作业 本次作业的UML类图 本次作业的度量分析 第三次作业 本次作业的UML类图: ...

  10. 2020 OO 第一单元总结 表达式求导

    title: BUAA-OO 第一单元总结 date: 2020-03-19 20:53:41 tags: OO categories: 学习 OO第一单元通过三次递进式的作业让我们实现表达式求导,在 ...

随机推荐

  1. privacy policy 隐私政策

    privacy policy 隐私政策 privacy agreement css layout & ssr page flex & center & fonts demo h ...

  2. ng 设置动态的document title

    使用Title服务 相关文章 配置路由, 添加data.title参数 import { NgModule } from '@angular/core'; import { RouterModule, ...

  3. Flutter NotificationListener 监听列表的滚动

    import 'package:flutter/material.dart'; import 'package:flutter_imagenetwork/flutter_imagenetwork.da ...

  4. 投资者通过这几种方式可以快速在NGK赚取收益

    2020年全球经济危机,各国经济持续低迷,资本市场变得躁动不安.而区块链市场,却异常火爆.各种公链项目相继而起,DeFi.分布式存储一个比一个火爆.NGK公链,无疑成为了这场热潮中有力的推动者之一,一 ...

  5. 喜忧参半的SQL Server触发器

    SQL Server触发器在非常有争议的主题.它们能以较低的成本提供便利,但经常被开发人员.DBA误用,导致性能瓶颈或维护性挑战. 本文简要回顾了触发器,并深入讨论了如何有效地使用触发器,以及何时触发 ...

  6. PHP中间件

    定义 首先什么是php的中间件? 根据zend-framework中的定义: 所谓中间件是指提供在请求和响应之间的,能够截获请求,并在其基础上进行逻辑处理,与此同时能够完成请求的响应或传递到下一个中间 ...

  7. Linux Cron 定时任务

    作者:丁仪 来源:https://chengxuzhixin.com/blog/post/LinuxCron-ding-shi-ren-wu.html 定时任务是经常被用到的,比如系统备份.数据导出等 ...

  8. 第41天学习打卡(死锁 Lock synchronized与Lock的对比 线程协作 使用线程池)

    死锁 多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形.某一个同步块同时拥有"两个以上对象的锁"时 ...

  9. xmake v2.5.2 发布, 支持自动拉取交叉工具链和依赖包集成

    xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...

  10. RocketMQ(4.8.0)——Broker 的关机恢复机制

    Broker 的关机恢复机制 一.Broker关机恢复概述 Broker关机恢复是指恢复 CommitLog.Consume Queue.Index File 等数据文件.Broker 关机分为正常调 ...