OO第一单元总结__多项式求导问题
作业一、含幂函数的简单多项式的求导
(1)基于度量的程序结构分析
1. 统计信息图:

2. 结构信息图:

3. 复杂度分析
基本复杂度(Essential Complexity (ev(G))、模块设计复杂度(Module Design Complexity (iv(G)))、Cyclomatic Complexity (v(G))圈复杂度

OCavg为平均循环复杂度;WMC为总循环复杂度

4. 分析:
本次作业一共使用3个类,没有使用继承、接口。
Main类:
1)程序入口
2)主要业务逻辑层
3)处理输入String
Polynomial类:处理多项式
1)正则表达式判WF(大正则)
2)简化输入String
3)分解成单项式:
用ArrayList<String>储存
3)组合单项式的输出String:
最终将ArrayList<String>转为String
4)简化输出String
Deviation类:单项式求导
1)求导
2)生成输出String
(2)程序BUG分析
1. 强测中未被查出BUG,但由于-1*cos(x)未被简化成-cos(x),被扣了性能分。
| 输入 | 我的输出 | 原因 |
| -sin(x) | -1*cos(x) | 在优化时只优化了+1*x-->+x,忘记了-1的情况,并且测试也不全面 |
2. 互测中未被查出BUG
(3)程序测试分析
1. 本次作业同学们的BUG集中在WF方面,/f,/v,+,**,末尾加空格等情况可能没有判出WF(BUG类似,不一一列举)。
2. 个人觉得一个有效解决非法字符的办法是先将正确字符从输入表达式中删除,再判断输入是否为空,不为空则WF。
3. 本次测试方法是构造各种WF的数据。
作业二、含三角函数的普通多项式的求导
(1)基于度量的程序分析
1. 统计信息图:

2. 结构信息图:

3. 复杂度分析
基本复杂度(Essential Complexity (ev(G))、模块设计复杂度(Module Design Complexity (iv(G)))、Cyclomatic Complexity (v(G))圈复杂度

OCavg为平均循环复杂度;WMC为总循环复杂度

4. 分析:
本次作业一共使用4个类,没有使用继承、接口。
Main类:
1)程序入口
2)主要业务逻辑层
InputHandler类:
1)处理输入String
2)少部分判WF
3)简化输入String
Polynomial类:处理多项式
1)大部分判WF(大正则)
2)分解成单项式:
用ArrayList<String>储存
3)组合单项式的输出String:
最终将ArrayList<String>转为String
4)简化输出String:
合并同类项,去0项,去1*,去-1*,找到正项做首项并去掉+, cos(x)^2+sin(x)^2 合并(任意系数的可合并项)
Monomial类:处理单项式
1)合并同类项
合并后形如 a*x^b*sin(x)*c*cos(x)^d
2)求导:
对于一个单项式,设其为a*x^b*sin(x)*c*cos(x)^d,再设其导数为A1*x^B1*sin(x)*C1*cos(x)^D1 + A2*x^B2*sin(x)*C2*cos(x)^D2 + A3*x^B3*sin(x)*C3*cos(x)^D3,通过数学运算可求出各参数值。
3)生成输出String
(2)程序BUG分析
1. 强测中未被查出BUG,但由于只做了一部分优化,被扣了性能分。
e.g. sin(x)^3*cos(x)+sin(x)*cos(x)^3 可化简为--> sin(x)*cos(x) ,但是这种化简比较复杂,我为了保证正确没有实现。
2. 互测中未被查出BUG
(3)程序测试分析
测试方法:我用之前构造的测试样例先大致测试一遍,在观察一些易考察的部分(如:正则表达式),进行针对性测试。
本次debug情况如下:
| 输入 | 输出 | 原因 |
sin(x) * sin(x) * cos(x) ^-2 *x |
WRONG FORMAT! | 无法识别多个三角函数连乘 |
作业三、支持嵌套的复杂多项式的求导
(1)基于度量的程序分析
1. 统计信息图:

2. 结构信息图:

3. 复杂度分析
基本复杂度(Essential Complexity (ev(G))、模块设计复杂度(Module Design Complexity (iv(G)))、Cyclomatic Complexity (v(G))圈复杂度

OCavg为平均循环复杂度;WMC为总循环复杂度

4. 分析
本次作业一共使用10个类,没有使用接口,使用了一层继承。
Main类:
1)程序入口
2)主要业务逻辑层
InputHandler类:
1)处理输入String
2)部分WF
factors包:
Factor类(父类):
1)抽象函数derivation public abstract String derivation();
2)FactorTri类(三角函数因子类):
2.1)将嵌套的因子用 content 保存:
content = string.replaceAll("^sin\\(", "").replaceAll("\\)(\\^[+\\-]?\\d+)?$", "");
2.2)区分sin、cos private Pattern patternSin = Pattern.compile("^sin\\(");
private Pattern patternCos = Pattern.compile("^cos\\(");
2.3)判断WF(指数>10000)
2.4)求导
3)FactorX类(幂函数因子类):
3.1)求导
items包:
CombinationItem类(父类):
1)定义最大递归深度(将非法数据判为WF)(每调用一次depth++):
if (depth > 95) {
System.out.println("WRONG FORMAT!");
System.exit(0);
}
2)定义抽象函数derivation public abstract StringBuilder derivation();
3)定义函数beakdown,将str以sign分割为List ArrayList<String> breakDown(String str, String sign) ,并判断WF
4)ItemAdd类(加法组合项类):
4.1) ArrayList<String> addList = breakDown(string, "+-");
4.2)对addList每一项判断
4.2.1)若string为表达式因子之外的因子,直接求导,以stringBuilder返回值
4.2.2)其他情况调用itemMultiIply类,进入下一轮递归调用
ItemMultiIply itemMultiIply = new ItemMultiIply(addList.get(i), depth + 1);
stringBuilder.append(itemMultiIply.derivation());
5)ItemMultilply类(乘法组合项类):
5.1) ArrayList<String> multList = super.breakDown(string, "*");
5.2)链式求导,调用itemNesting类
6)itemNesting类(嵌套组合项类):
6.1)判断是否有嵌套,同时判断WF
6.2)若有()类嵌套,调用itemAdd类
6.3)若有sin()、cos()类嵌套
6.3.1)如果内含为表达式因子之外的因子则直接返回stringBuilder
6.3.2)否则调用itemAdd类(用多flag参数的构造函数并设flag=1)和FactorTri类
6.4)其他情况
6.4.1)flag = 0则调用itemAdd类
6.4.2)flag = 1则WF
OutputHandler类:
1)防止输出空字符串
2)输出String
(2)程序BUG分析
1. 强测中未被查出BUG,但为了保证正确性,没有做优化,性能分为0。
2. 互测中被查出1个BUG,如下:
| 输入 |
-(+(+1*cos(x)))*cos((x-cos(x))) |
| 我的输出 |
-(+(((+(((+0+(-1*sin(x)*1)*1))))))*cos((x-cos(x)))+(-1*sin((x-cos(x)))*((1--1*sin(x))))*(+(+1cos(x)))) |
| 错误原因 | 我在处理连乘项的时候,用 replaceFirst("\\*", ""); 取代第一个乘号,但第一项前面没有*,所以替换了一二项间的*,导致出错 |
| 解决方案 | 用 replaceALL("^\\*", ""); 代替了上述代码,解决问题 |
这个BUG属于考虑不全面造成的错误,测试时也未覆盖到(测试样例太少,复杂测试样例更少)。
(3)程序测试分析
测试方法:我用之前构造的测试样例先大致测试一遍,在观察一些易考察的部分(如:有无使用BigInteger包),进行针对性测试。
反思:全程手动,无自动化工具,所以效率不高,希望以后能学习使用自动化测试技术。
debug的部分情况如下:
| 输入 | 输出 | 原因 |
13412312235423432 |
WRONG FORMAT! | 没用BigInteger |
---2 * x |
2 | ---识别为+ |
- x^+4*sin(x)^7+12*x^0001+ + +12*x-123- - x+12 |
WRONG FORMAT! | 无法识别+ + +12 |
- x^+4*sin(x)^7+12*x^0001+ + +12*x-123- - x+12 |
-((7*sin(x)^6*cos(x)*(+1))*1+0)*(x^4)+sin(x)^7*1*(4*x^3)+12+12-0+1+0 |
计算错误 |
((sin (x ^ +1) ^ +10000)) |
WRONG FORMAT! | +10000认为>10000 |
((sin (x ^ +1) ^ +10000)) |
WRONG FORMAT! | 中间tab无法识别 |
((sin (x ^ +1) ^ +10000)) |
java报错 |
创建了0长度的BigInteger |
Applying Creational Pattern
第三次作业中用到了继承,但是没有对象构建的模式,仍旧是面向过程式的想用某个项时,特殊调用某个项。借鉴了各路大神的思路,有了初步的想法。通过一个工厂函数,将当前字符串输入,返回一个对应类的对象。代码如下:
public static Factor factorFactory(String str) {
if (str.contains("sin")) {
return new FactorSin(str);
} else if (str.contains("cos")) {
return new FactorCos(str);
} else {
return new FactorX(str);
}
}
总结
1)面向对象的思维在三次作业中逐渐建立起来,但是代码实际上还是面向过程,有待改进。
2)对于java一些包的使用不熟练,只会用几个基本的包(BigInteger、ArrayList、StringBuilder等)。
3)优化太少,且多为面向数据的优化,很少建立优化规则。
4)手造测试数据太随便,应该进行分模块的覆盖性测试。
5)代码耦合度太高,需要解耦
6)好的构造思路远比“打补丁”高效
希望多思考,多实践,多看大佬分享的思路,OO加油啊~
OO第一单元总结__多项式求导问题的更多相关文章
- OO第一单元作业总结——表达式求导
OO第一单元作业总结 第一次作业 基于度量分析代码结构 基本算法 第一次作业是简单多项式导函数求解,不需要对输入数据的合法性进行判定, 基本思想是用 (coeff, expo)表示二元组 coeff* ...
- OO第一单元总结(表达式求导)
写在前边:第一次接触面向对象语言,编程思想仍然不可避免的有以前面向过程的影子.从第一次作业的完全面向过程,到第二次学会剥离各个类互不影响到第三次作业的先构思面向对象的基本程序架构再编程.虽然程序有些地 ...
- OO第一单元总结-多项式求导
OO第一单元总结-多项式求导 一.第一.第二次作业总结 因为前两次作业设计复杂度差别不大,因而放在这里统一总结. 基于度量分析程序结构: 前两次作业确实存在缺乏可拓展设计的构想,基本还是面向过程的思维 ...
- OO第一单元(求导)单元总结
OO第一单元(求导)单元总结 这是我们oo课程的第一个单元,也是意在让我们接触了解掌握oo思想的一个单元,这个单元的作业以求导为主题,从一开始的加减多项式求导再到最后的嵌套多项式求导,难度逐渐提高,编 ...
- 2020 OO 第一单元总结 表达式求导
title: BUAA-OO 第一单元总结 date: 2020-03-19 20:53:41 tags: OO categories: 学习 OO第一单元通过三次递进式的作业让我们实现表达式求导,在 ...
- OO_多项式求导_单元总结
概述: 面向对象第一单元的作业是三次难度依次递增的多项式求导.第一次作业是仅包含带符号整数和幂函数的多项式求导,例如:-1+xˆ233-xˆ06:第二次是在前面的基础上增加了三角函数的求导,例如:-1 ...
- 多项式求导系列——OO Unit1分析和总结
一.摘要 本文是BUAA OO课程Unit1在课程讲授.三次作业完成.自测和互测时发现的问题,以及倾听别人的思路分享所引起个人的一些思考的总结性博客.本文第二部分介绍三次作业的设计思路,主要以类图的形 ...
- OO第一单元作业总结
oo第一单元的作业是对多项式的求导.下面就是对三次作业分别进行分析. 第一次作业 分析 第一次作业相对来讲比较简单,甚至不用面向对象的思想都能十分轻松的完成(实际上自己就没有使用),包含的内容只有常数 ...
- OO第一单元总结
OO第一单元作业总结 一.前言 开学四周,不知不觉已经做了三次OO作业.事实上,每一次作业对我来说都是很大的挑战,需要花费大量的时间和精力来学习. 虽然学得很艰苦,但最后还是连滚带爬地完成了.(好惨一 ...
随机推荐
- 2019-03-29 Vagrant Docker Toolbox 下载安装
1.无脑安装Vagrant Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境.它 使用Oracle的开源VirtualBox虚拟化系统,使用 Chef创建自动化虚拟环境. http ...
- 原生js,时间日期简单应用。
一.数码时钟,滚动切换时间. <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...
- tomcat设置编码utf8
1. Java类: CharacterEncodingFilter import javax.servlet.*; import java.io.IOException; public ...
- [ES6] Proxy & Reflect
Proxy and Reflect API works nicely together. About how to use Proxy, check this post. Let's see abou ...
- C# 跨线程调用form控件技巧及byte[]与string型相互转换
跨线程调用form控件技巧 private delegate void MethodSocket(object obj);//使用托管 ss = "OK"; this.BeginI ...
- html5开发手机打电话发短信功能,html5的高级开发,html5开发大全,html手机电话短信功能具体解释
在非常多的手机站点上,有打电话和发短信的功能,对于这些功能是怎样实现的呢.事实上不难,今天我们就用html5来实现他们. 简单的让你大开眼界.HTML5 非常easy写,但创建网页时,您常常须要反复做 ...
- 升级Xcode8后的相机crash问题-IOS10权限问题
当我升级到Xcode8后,启动我的相机项目,直接crash,输出的日志如下: '2016-07-08 16:41:11.268943 project-name[362:56625] [MC] Syst ...
- oracle 11g rac 修改VIP、scan VIP、priv IP
11GR2 RAC modify vip,public ip,private ip,scan vip实施步骤1 修改目的 根据业务的需求,需要由原来的临时IP改为生产ip,以下为调整前后对应的I ...
- 【POJ 2481】 Cows
[题目链接] http://poj.org/problem?id=2481 [算法] 树状数组 注意特判两头牛的s,e值相同 [代码] #include <algorithm> #incl ...
- HttpClient连接超时及读取超时
HttpClient连接超时及读取超时 httpClient在执行具体http请求时候 有一个连接的时间和读取内容的时间: HttpClient连接时间 所谓连接的时候 是HttpClient发送请求 ...