BUAAOO第一单元的总结
---恢复内容开始---
Homework1 简单多项式求导
程序架构

由于对java的生疏和不了解,第一次作业很羞愧的只用了一个类。
1.在输入之后调用Polyformat函数检查输入的格式,A检索有无非法字符,B检索有符号整数格式,C消除所有空格并对表达式前加符号。
2.调用Poly构造器,使用正则表达式对表达式进行处理,将得到的一个个因子的导数调用addhash存入hashmap中,并在检索完成之后再对所得到的字符串的长度求和并与传入Poly的表达式长度比较来完成最后一次格式检查。
3调用PolyPrint将hashmap中的表达式整理化简并且输出。
BUG的出现
1.输入对\S和 与\t的混淆。
for (int i = 0; i < str.length(); i++) {
if (!str.substring(i, i + 1).matches("[\\d\\sx*^\\+\\-]")) {
return "WRONG FORMAT!";
}
}
如上代码就会导致对本应该判定WF的\f输入却判定为正常输入。
应该修改为如下代码:
if (!str.substring(i, i + 1).matches("[\\d\\t x*^\\+\\-]")) {
return "WRONG FORMAT!";
}
2.对当输入为空串或者是hashmap为空时无任何输出。这个修改也较为简单在此不多赘述。
Homework2 包含简单幂函数和简单正余弦函数的导函数
程序架构

第二次作业对第一次作业的复用非常多。
1.PolyFormat类只是从之前的Poly类分出来用于美观,其中检查方法几乎不变,只是对sin(x)cos(x)等字符的引入和对+++等几个小细节的检查增加罢了。
2.在Poly类的构建之中,思路仍然一样,即将项一个一个分出来,然而对项的处理我是直接统计x的次数,sin(x)的次数和cos(x)的次数和系数,分成这四个部分,再直接应用乘法求导法则,将这个项的求导分成三个导数生成,再将这三个导数录入hashmap,当然hashmap也有所变动,它的key化为了XSinCos类,而value仍然是系数,然后在存入时完成合并同类项工作。
3最后在PolyPrint中输出。
BUG的出现
说起来也冤,我的一个化简bug被强测de了5个,直接导致强测爆炸。直接上错误代码
for (int i = 0; i < ss.length() - 1; i++) {
if (ss.charAt(i) == '1' && ss.charAt(i + 1) == '*') {
ss.delete(i, i + 2);
}
}
我做出了极其愚蠢的优化,原本我是为了化简一个项前多出的1*,然而一旦进行上述的代码操作就会使所有包含1*的式子都被消去,例如21*x会被化简为2x,例如x*sin(x)^1*cos(x)会被化简为x*sin(x)^cos(x)。
Homework3 包含简单幂函数和简单正余弦函数的导函数
程序架构
在第三次作业,我完全推翻了前两次作业的架构,因为有了嵌套,我无法仅仅通过简单的正则表达式从一串表达式中提取我所需要计算的项,因此前两次的架构是完全无法适用第三次作业的。
1.使用PolyFormat的FirstCheck()进行如第一二次作业的最基础的检查,这个检查非常基础,仅仅是初次的排除很明显的格式错误。
2.用ParenPro对表达式进行切分处理。具体细节:使用栈从内向外对括号进行检查,从最内层的括号开始提取括号中的式子并且将它替换为y1,y2,y3……例如3*sin(cos(x))*(1+3*x)会被替换为3*sin(y2)*(y3),而y2为cos(y1),y3为(1+3*x),y1为x,注意替换的差异:sincos(x)和(表达式)不同,因为还需要对yi进行format检查,而sincos()内仅仅只能是因子,而(表达式)里可以是表达式也可以是因子(*单一因子也是表达式),所以替换有差异,而且(表达式)是要将括号也替换,而sincos只要将括号中的内容替换即可。替换的yi存入ParenPro的hashmap中,yi为key,yi代表的串为value,用于之后的递归调用。
3.在替换过程中,调用PolyFormat中的checkFactor()检查sincos的yi所表示的因子,用checkExp()检查(表达式)的yi所表示的表达式,内部即可用正则即可,因为在2.中是由内向外分解括号的,因此保证yi所表示的式子最多只有单层括号存在,即sin()和cos(),当然还得注意因子的增加,yi因子和sincos(yi)^的增加,只要使用正则表达式即可完成检查工作。
4.完成替换工作,即可将替换完的字符串传入Expression类中进行求导,Expression对字符串进行分割,将分割的一个个项传入Term中进行运算,Term中继续分割项为因子,将因子传入Factor项中进行运算,Factor中完成递归调用,若为普通因子直接计算,若含有yi,从hashmap中调出yi的字符串再次传入Expression中进行运算,从而完成递归调用工作。
5.最后传出的求导字符串仍然含有yi,因此要最后一次调用change函数再次使用hashmap将yi依次替换,最后就为求出的式子。
复杂度分析



可以看出PolyFormat的FirstCheck函数的非结构化程度和结构复杂程度都十分高,这就是因为它调用众多正则表达式并进行多次单独的循环判断所造成。而Factor类的detivationFac的程序耦合度相当高,因为它是进行递归的环节,需要再次调用Expression类,并且我对每个因子都创建了一个求导方法,从而造成耦合度高、独立路径多。我感觉在这两块上还是有太多欠缺 的地方了。
BUG的出现
第三次最主要的一个bug就是对sin(- 10)的输入无法判断为WF,其主要原因就是FirstCheck()的处理出现问题。由于对第二次代码的复用,没有考虑sincos()检查内部是否为因子的操作,在firstcheck中只会检查有符号整数是否正确,然后去空格,从而导致原本为表达式的- 10被化简为因子-10,从而产生bug。我思考了一下,直接在firstcheck中加入特判,因为sincos(- 10)的出现仅仅会出现在最内部的括号中,即第一次检查一定可以检查到,所以用正则特判就能解决这个问题。
三次作业总结
优点
没有使用长正则表达式,而是使用while(m.find){m.group()}的结构对表达式进行拆分判别,从而减少了爆栈的出现。
缺点
十分多
1:表达式化简极其偷懒。虽然第一二次都进行了化简,但是第三次作业几乎没有化简,造成大量多余括号和*1、*0的出现使表达式变得臃肿冗余。
2:对面向对象的理解十分浅薄。虽然第三次分成了Exp、Term、Factor类,但是类之间耦合关系仍然严重,面向过程化仍然严重。
3:程序的适用性很差。因为没有太多考虑架构问题,如果有所变动,可能需要大改。
4:鲁棒性很差。对于try-catch的使用太过于生疏(其实根本没有用),造成奇怪的输入就可能会使程序崩溃。
总结
总的来说,第一单元的作业算是java的入门,但是也非常的艰难,因为从无到有的过程本身就是最为艰难的。我还有许多欠缺的,对整个程序的架构,对继承接口等掌握,对try-catch的熟悉,还有对调试的熟练程度都是我应该重视并且赶紧练习的。我也没啥好的经验能和大家分享的,只有继续向大家学习。
---恢复内容结束---
BUAAOO第一单元的总结的更多相关文章
- BUAA-OO第一单元小结
引言 四周过去了,oo课程的第一阶段作业也算告一段落.在第一单元的内容中,主题是始终如一的多项式求导,但三次作业要求完善的求导功能一次比一次丰富,难度也逐渐增加,也是费了不少心思.接下来就回顾与小结一 ...
- BUAAOO第一单元代码分析
1.HomeWork1 思路 一个主类用于字符串得操作, 一个Poly类用于对一个多项式进行抽象,用Arraylist来对term进行封装.内部含有求导方法,添加并合并同类项的方法,toString方 ...
- 2020 OO 第一单元总结 表达式求导
title: BUAA-OO 第一单元总结 date: 2020-03-19 20:53:41 tags: OO categories: 学习 OO第一单元通过三次递进式的作业让我们实现表达式求导,在 ...
- 【BUAA-OO】第一单元作业总结
#OO第一单元作业总结 #确认存活,爱学习,爱北航,爱OO 一.三次作业分析 1.第一次作业 1.1 程序结构 对方法的度量: 类的内聚和相互间的耦合情况: 类图: 优缺点: 优点大概没什么优点,毕竟 ...
- OO第一单元作业小结
前言 第一单元的主题是表达式求导,第一次作业是只带有常数和幂函数的求导,第二次作业加入了正余弦函数,第三次作业又加入了表达式嵌套,难度逐渐提升.总体来说前两次作业还易于应对,而第三次作业做得相对有些艰 ...
- BUAA面向对象设计与构造——第一单元总结
BUAA面向对象设计与构造——第一单元总结 第一阶段:只支持一元多项式的表达式求导 1. 程序结构 由于是第一次接触面向对象的编程,加之题目要求不算复杂,我在第一次作业中并没有很好利用面向对象的特点, ...
- 2019_BUAAOO_第一单元总结
前言 OO第一单元共有三次作业,分别为多项式求导.带有三角函数与幂函数的表达式求导.带有嵌套表达式因子的表达式求导.虽然这三次作业都离不开求导,可是每次作业的复杂度都是大大递增的.对于习惯于面向过程编 ...
- OO第一单元作业总结
oo第一单元的作业是对多项式的求导.下面就是对三次作业分别进行分析. 第一次作业 分析 第一次作业相对来讲比较简单,甚至不用面向对象的思想都能十分轻松的完成(实际上自己就没有使用),包含的内容只有常数 ...
- OO第一单元总结
OO第一单元作业总结 一.前言 开学四周,不知不觉已经做了三次OO作业.事实上,每一次作业对我来说都是很大的挑战,需要花费大量的时间和精力来学习. 虽然学得很艰苦,但最后还是连滚带爬地完成了.(好惨一 ...
随机推荐
- 基于卷积神经网络CNN的电影推荐系统
本项目使用文本卷积神经网络,并使用MovieLens数据集完成电影推荐的任务. 推荐系统在日常的网络应用中无处不在,比如网上购物.网上买书.新闻app.社交网络.音乐网站.电影网站等等等等,有人的地方 ...
- Jenkins去GitLab拉取Java代码自动打包
jenkins的部署 一.部署git 1)先检查系统是否已经自带了git,如果有,就卸载 $ rpm -qa | grep git && rpm -e git --nodeps 2)开 ...
- vue-router的简单理解
Vue-router原理了解一下: 找到一篇文章,分析的很透彻 从vue-router看前端路由的两种实现,文章写的很好,看完这篇文章 ➕ 看源码应该可以理解,这里根据我浅显的理解概括一下: vue- ...
- Hadoop入门
一.Hadoop是什么 1)Hadoop是一个由Apache基金会所开发的分布式系统基础架构. 2)Hadoop主要解决,海量数据的存储和海量数据的分析计算问题. 3)广义上来说,Hadoop通常是指 ...
- 浮点型/小数/栅格图层转为整数型arcgis操作
有时候会遇到将32位栅格数据提取属性表的操作,但是一般此类数据都是浮点型,是无法计算得到属性表的.因此我们可以利用数据管理工具下的: 复制栅格工具,在最下面选择16位即可,看自己数据情况选择signe ...
- Cordova入门系列(四)自定义Cordova插件--showToast
前三篇Cordova入门系列,简单讲解了Cordova,以及如何调用Cordova插件,今天我们讲解一下如何自己做一个插件. 自定义插件,就是自己写一些安卓java代码,然后和js代码以及配置文件,封 ...
- k个一组翻转链表(java实现)
题目: 给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度.如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序. 示例 : 给定这 ...
- tomcat: 类加载器
一.tomcat是个web容器,要解决以下问题 1. 一个web容器可能要部署两个或者多个应用程序,不同的应用程序,可能会依赖同一个第三方类库的不同版本,因此要保证每一个应用程序的类库都是独立.相互隔 ...
- 《javascript经典入门》-day02
<javascript经典入门>-day02 1.使用函数 1.1基本语法 function sayHello() { aler('Hello'); //...其他语句... } #关于函 ...
- 关于requestAnimationFrame与setInterval的一点差异
requestAnimationFrame与setInterval都可以实现循环触发事件,但是setInterval是基于时间的,而requestAnimationFrame是基于帧数的,在我的一次开 ...