OOP 第一章作业总结
程序设计结构分析
类图分析
第一次作业
由于第一次作业完成的功能比较简单,而且出于对面向对象设计理念不熟悉(其实现在也不是很熟悉,逃),整个程序设计的非常简单。通过类图(见下)可以看出,程序只有两个类:PolyCal 包含 main 方法,充当表达式类的功能,并且完成对输入的解析;Poly 充当项类,管理一个项内的因子,并向 PolyCal 提供服务。
第二次作业
这次作业虽然较上一次而言,划分出了很多类,但其实与第三次作业助教提示的设计架构仍有较大的差距,面向过程的意味仍然非常明显。PolyCal 仍然是充当表达式类,包含 main 方法,并且自己解析输入,完成求导并化简等诸多功能,剩下的其他类都是充当它的辅助,可以看出 PolyCal 类的功能过于复杂,不可取。

第三次作业
借由助教的提示,这次将 Main 单列成一个类,而且完成逻辑业务的框架由三个大类组成,表达式、项类、因子类。Main 类负责创建并维护一个 Expression 类的实例,将初步处理过的输入交给表达式类解析,表达式类的解析则是表达式创建项类将输入交给他们解析。不过,这个架构也有不足之处,第一,我把优化输出即去掉多余括号的大多数工作交给了 toString() 方法,这直接导致了后面遇到了未知的 TLE bug,调式时没法查看当前变量,因为查看会调用 toString() 方法,而 toString() 出了 bug;第二,对于输入解析的处理仍然非常暴力,直接导致了 Poly 类复杂度爆炸。

复杂度分析
由于方法复杂度的截图过长(方法数太多了,严重影响阅读体验),所以这里只挑我发现的重点问题说。三次作业方法复杂度超标比例为 1:3/12;2:5/28;3:17/53,类复杂度如下图。
- 分析总结
- 由于方法中使用了大量的 if-else 控制语句,导致三次作业的部分方法圈复杂度比较高
- 由于并未将解析表达式的功能单列出来,导致了第一、二次作业 PolyCal 与第三次作业 Poly 类复杂度偏高
- 由于将优化放在了表达式类中,导致后两次作业的 PolyCal, Expression 类的复杂度偏高
自己程序的bug -- 优化 bug
后两次作业强测中挂掉的数据点,最后发现都是由于自己优化的锅,在这里检讨一下。
第二次作业
- 第二次作业主要是三角函数的优化,当时我采用的是数学公式硬优化,从 sin(x)^2 + cos(x)^2 = 1 开始推导,得到了在一定前提条件的情况下,能够实现三角函数化简。但是最后写代码的时候把 if 条件语句的前提条件写错了。仔细想一下,虽然这只是由于一个失误造成的 bug,但是这种单靠数学公式推导的方式来进行化简的思路,本身就是足够复杂的,不能算得上比较好优化方法。
- 这里分享一下研讨课上听到某位大佬介绍的优化方法 -- 启发式算法
一个基于直观或经验构造的算法,在可接受的花费(指计算时间和空间)下给出待解决组合优化问题每一个实例的一个可行解
- 本次作业的优化,就是基于 sin(x)^2 + cos(x)^2 = 1 这条经验,通过迭代循环优化来实现的。起始,将未优化表达式放入 TreeMap 中,每次迭代循环过程中,将 TreeMap 中最短的表达式取出,随机选择其中一项将其中的 cos(x)^2 或 sin(x)^2 化成 1 - sin(x)^2 或 1 - cos(x)^2,再去合并同类项,将新的表达式放入 TreeMap 中。这样做,虽然并不能保证一定能优化出优于原解的表达式,但其执行时间可控,可以在一定程度上避免自己的程序因为优化而造成 TLE
- 关于更多启发式算法,这里推荐一篇帖子
第三次作业
第三次作业,我想采取的优化也仅仅是去掉多余的括号,如果项中含有一个因子为 0(或 sin(0) 等)那么整个项 toString 返回一个空串,以及如果表达式因子仅含有一个项,那么输出它的时候,就去掉括号,以及尽可能的合并同类项。现在回顾看来,这些优化的实现方法都存在问题,下面分享一下心得体会。- 表达是因子的去括号的操作应该交给字符串输入解析类来完成,即通过栈来检查括号匹配,查看是否首尾括号恰好内嵌一对括号。
- 注意 ArrayList.addAll() 是浅拷贝,意味着,它只是把索引赋了过来,若后面对索引对象进行了值修改,会导致本不想修改的原对象也被修改了。这里建议以后尽量采用不可变对象,任何修改值的方法都是返回一个新的对象。
- 不应该将优化操作放在 toString() 方法内部
互测发现别人的 bug
由于后面两次作业优化都出了巨大 bug,所以被分到了 bug 较多的 C 组,所以检查别人 bug 难度相对较低,我采取的是,先把所有人的代码文件夹集中到一个目录下,先通过 javac 编译,然后就可以用 .sh 文件快乐的,一次测所有人的代码了。除此之外,还用 python 的 Xeger 和 sympy 包,搭了一个简易的自动对拍器,但遗憾的是,正则表达式没法生成嵌套,所以第三次作业并没能很好的自测到自己的 bug。
应用工厂模式解析输入字符串
因为观察到,由项来实现对字符串的解析取出每一个因子然后生成对应的因子对象,导致项类的复杂度过高;而且不同种类的因子生成都非常类似,找到对应的字符串,传递给构造器即可。所以可以创建一个工厂接口,为每位因子实现一个工厂生成方法,在项类仅需要通过正则表达式判断一下当前需要解析的因子是哪一种的,然后就可以通过工厂接口变量实例化对应的工厂方法,来生成对应的因子,减轻项类的工作负担。
public interface ParseFactor{
public ArrayList<Object> parse(String input);
// 因为我不仅需要返回新建的因子对象而且需要返回解析过剩下的字符串
}
OOP 第一章作业总结的更多相关文章
- OOP第一章总结
经过了三周的OO,尽管过程不太轻松,但是有所得还是值得欣慰的事! (1)程序结构 第一次作业: UML类图如下,第一次作业在结构上并没有太多面向对象的思想,只是简单的分类,一个运行类,两个对象类,预处 ...
- OOP 第二章作业总结
实现策略 这里结合一下我画的第三次作业的时序图(可能有画的不好的地方)来叙述一下我的实现逻辑.最开始主线程负责创建必要的线程(输入.调度线程)与请求队列类实例:输入线程负责与人进行交互,将获取到的请求 ...
- Java OOP——第一章 对象和封装
1.软件出现的目的: 用计算机的语言描述现实世界 用计算机解决现实世界的问题 ◆面向对象设计和开发程序的好处: 交流更加流畅 提高设计和开发效率 计算机语言的发展向接近人的思维方式演变 ...
- linux系统管理第一章作业
上机作业: 1.请用命令查出ifconfig命令程序的绝对路径 [root@localhost ~]# which ifconfig /usr/sbin/ifconfig 2.请用命令展示以下命令哪些 ...
- Metasploit魔鬼训练营第一章作业
1, Samba服务 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成.SMB(Server Messages Block,信息服务块)是一种在局域网上共 ...
- 《Metasploit魔鬼训练营》第一章实践作业
<Metasploit魔鬼训练营>第一章实践作业 1.搜集Samba服务usermap_script安全漏洞的相关信息,画出该安全漏洞的生命周期图,标注各个重要事件点的日期,并提供详细描述 ...
- 第一章 C++简介
第一章 C++简介 1.1 C++特点 C++融合了3种不同的编程方式:C语言代表的过程性语言,C++在C语言基础上添加的类代表的面向对象语言,C++模板支持的泛型编程. 1.2 C语言及其编程 ...
- SQL 第二章 作业
/*第二章 作业*/ create table S ( sno char(2) NOT NULL UNIQUE, sname char(3), city char(2) ); alter table ...
- 第一章ASP.NET SignalR简介
第一章ASP.NET SignalR简介 1.1概述: ASP.NET SignalR是微软新开发的类库,为的是帮助ASP.NET开发人员很方便地开发实时网络功能. SignalR允许服务器端和客户端 ...
随机推荐
- numpy 数组运算
数组的减法:不同维数
- 微信小程序遇到的问题与解决
1.微信开发工具报错 400 (Bad Request) 解决方法: 注:因为开发工具升级 content-type的写法变了 如下代码: header:{ "Content-Typ ...
- 百度联盟广告 http://cpro.baidustatic.com/cpro/ui/c.js
<script src="http://cpro.baidustatic.com/cpro/ui/c.js" type="text/javascript" ...
- 当页面滚动到距顶部一定高度时某DIV自动隐藏和显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 将yum源更换为阿里的源(脚本)
#!/bin/bash ######################################### #Function: update source #Usage: bash update_s ...
- ObjectARX二次开发创建自己的静态库,如同objectARX库一样
objectARX二次开发的时候,经常会用到一些重复使用的类,如果类已经足够的好,那么我们可以编译成静态库,加快开发和编译的速度,提高工作效率. 环境vs2010+objectARX2012wizar ...
- secureCRT颜色方案设置
按照如下设置后vim编辑会有如下颜色提示
- Vim查找与替换
\c 忽略大小写 \C 强制区分大小写 \v 除了_.字母.数字以为的所有字符都当做具有特殊含义的字符 \V 只有反斜杠有特殊含义 %s///gn 统计某个词出现的次数 替换的flag g 全局范围执 ...
- P4850 [IOI2009]葡萄干raisins 记忆化搜索
$ \color{#0066ff}{ 题目描述 }$ 普罗夫迪夫的著名巧克力大师Bonny需要切开一板带有葡萄干的巧克力.巧克力是一个包含许多相同的方形小块的矩形.小块沿着巧克力的边排列成n行m列,即 ...
- 第九届蓝桥杯大赛个人赛决赛(软件类)真题Java
更新中.......... 同一年的题解:https://www.cnblogs.com/dgwblog/p/10111903.html 01 结果填空 (满分11分) 标题:年龄问题 s夫人一向 ...