面向对象OO第一单元三次作业总结
(一)第一单元的作业围绕着多项式的求导,从简单到复杂,主要的要求是
作业一:只有两种格式的因子:带符号整数(+02)和幂函数(x^+02)。
作业二:在作业一的基础上添加了:sin(x)和cos(x)以及首项的第一个因子为+1或-1可以省略“1”
作业三:在作业二的基础上增加了 “表达式因子”的概念:用括号括起来的整个表达式,如(x+sin(x)),另外sin()和cos()的括号中可含所有因子,如sin(+2),sin(x^2),sin(sin(x)),sin((x+x))
(二)我三次作业的思路:
作业一:由于只有两种固定格式的因子(+1,+x^+1),所以我用的是状态机,一共分了九个状态,并同时分别统计系数和指数,然后统一求导。我的主要的方法行数超过了60行——但如果我把判断格式合法性和统计系数指数分开成两个方法的话,就不会超了
作业二:由于增加了sin(x)和cos(x),而且在作业一中我的主要的方法的长度就远远超过了规定的60行,分开判断与统计也会超,所以我用了正则表达式来判断输入的合法性,正则表达式分为:
sin_cos:“[ \\t]*((sin)|(cos))[ \\t]*\\([ \\t]*x[ \\t]*\\)([ \\t]*\\^[ \\t]*[+-]?\\d+[ \\t*])?”
x :"[ \\t]*x[ \\t]*(\\^[ \\t]*[+-]\\d+)?"
d :"[ \\t]*[+-]?\\d+"
整串的判断就为: “([ \\t]*[+-]?(sin_cos|x|d)[ \\t]*(\\*(sin_cos|x|d)[ \\t]*)*)+”,即将整串分为 “(首个因子(*后面的因子——可能没有))+”的格式。
然后处理字符串,让各个加数能以“+”直接被“split”出来,各个乘数能以“*”直接被split出来,再一个个分别求导。
由于格式固定,正则表达式真的超好用,不过有时候爆栈就不好用了。
作业三:表达式不固定了——但还是有套路——factor,sin((factor))。由于目前java的正则表达式不能判断所有的括号是否匹配,所以我选择的是“逐层判断”,先将字符串转换成数组,逐一将最外层的括号及其里面的东西转换成一个字符“?”(好吧这非常不“面对对象”),然后判断当前表达式是否为这四种“因子”:
sin_cos: sin?形式(空格、指数之类的与上面的一致,就不写了,下面同)
x:与上面一致
d:与上面一致
表达式因子:\\?
所以整串的表达式判断类似于:“([+-]?((sin_cos)|x|d|(\\?))(\\*((sin_cos)|x|d|(\\?))))+*”(空白字符及最开头的+1省略之类的就不表示出来了)
到这里可能会问:那括号里面的东西不合法怎么办?我是这样做的:
在判断最外层的合法后:
将当前的整串交给负责“初次求导”的“求导一号”去办,它们会将整串遍历以分出各个加数、然后将各个加数送去“求导二号”,
“求导二号”会将当前送来的加数分成各个乘数——有sin()形式,有x^2形式,有+2形式,有()形式,然后又将这些乘数送给对应的“各小求导部门”——专门负责求sin()形式的、专门负责求x^2形式的、专门负责求()形式的,(至于纯数字的乘数,会让它保留在“求导二号”,等大家都求完导回来后再和大家汇合)。另外在这个方法里面我还将当前表达式中所有的sin()形式的因子和()形式的因子分别统计成了两个动态数组,记为A、B,用途我后面再说。
而“各小部门”又会先各自检查自己的字符串的“最外层”是否合法——主要是sin()形式和()形式的——因为它们里面的还要求导嘛,而且x形式的之前已经判断过了,于是乎,它们在提取出最外层括号里面的表达式之后,就将剥出来的“小表达式”送入下一层的判断(一样的类、一样的方法——“()”变成“?”那个)、小表达式又会经过求导一号、求导二号、各小部门。。。
直到最后的表达式不含括号后,将其中规中矩地求完导,然后返回上一级。
然而,这里往下传递似乎很好想,可是,下一级的求完导后要怎样和上一级的汇合呢?
首先,我介绍下自己设定的类Val——包括 xs(系数),zs(x的指数),动态数组一号(各种奇怪的sin()、cos()及他们各自的指数,是的,这里面又有一个小类Valsin),动态数组二号(各种奇奇怪怪的(factor)形式),(毕竟其他的在求导时它们是不能变的嘛)。
所以,在每一个部门里面求完导之后都会返回一个ArrayList(Val),然后会一个一个取出这里面的东西,和当前的汇合——xs相乘,zs相加,(之前统计的两个数组的作用出来了——)动态数组一号将当前一级的A中的所有Valsin一个一个添加进去,动态数组二号将当前一级的B中的所有(factor)一个一个加入,然后再一层层返回。。。最后输出时,将当前的每一个Valsin一个个按 xs,zs arrayList(Valsin),arrayList(string)格式输出就行了。
是的,我没有做优化。。。
所以呢,结果就是我被hack了9个点。。。9个。。9.。。原因是在求sin((factor))形式、剥离里面的factor时由于没处理当,要么多了一个“)”要么只去掉了两头的空格,以及在里面判断是(factor)还是x^+2还是+2还是sin()时忘了【+-】?的“?”。好我马上分享我的bug“历史”。
(三)我三次作业被查出来的bugs和我的“hack手段”:
第一次:荣幸!由于用了状态机,各方面钉得死死的,我的“和平室友们”没有hack到我,不过我也只是用了边界数据——超长的表达式使他们的正则爆栈hack到了他们。
hack手段:查代码,主要是看正则表达式是否写错,比如[ \\t]*写成[ \\t]+的,或者用超长数据检测(在允许的范围内)
总结:第一次由于模式少、格式严格变动少,利用状态机或正则表达式很容易避免"WRONG FORMAT"的判断出错,不过爆栈是后话,我会在后面阐述为啥能爆栈
第二次:由于字符串的处理出了问题:对于已经合法的字符串,我的处理步骤是:
1,去掉所有空白字符;
2,将所有的"--"和“++”换成“+”;
3,将所有的“-+”以及不是“^-”以及不是“*-”以及不是“+-”的的带有“-”的换成“+-”;
4,将“^+”换成“+”,将“*+”换成“+”。
好吧我想已经看出问题了:第二步就将“--”“++”处理了的话,到第三步如果形成了“+--”形式的也不会再管了——而且我后面的处理也只是按照“+”分割,而且分割带符号整数和其它格式的因子时也只是“[+-]?\\d+”,然后“--d+”格式的就不会被读入并统计,输出结果永远为0.
第三次:我的第三次及其惨烈——由于字符串的处理没有到位:带括号的式子没有“.trim()”去掉最外层括号两边的空白字符就直接切割“substring(1,length-1)”,导致多出一个“)”或“(”或“()”,进入下一级时就会直接“WRONG FORMAT!”,以及正则表达式的出错:sin、cos中判断x^+01形式时“[+-]?”没有“?”,导致对于cos(x^4)我直接是"WRONG FORMAT!"(因为不是cos(x^+4)).
hack手段:由于我所在room的人的思路都差不多,都是按照“树结构”,所以我主要是看他们的代码,看字符串的处理、正则表达式、以及整合时有没有漏掉什么。
总结:根据互测和公测的数据,我的bug出现和结构无关,即总体思路还是没有错的(但是很“面对过程”);另外,判断、处理字符串这里面真的要非常仔细,很容易出错。
(四)重构:
第一次:格式的判断会用正则表达式,而且统计xs(系数),zs(指数)也会直接用matcher直接抓。
第二次:原有思路不变,但会设置存储时用harshmap类型存储——将x,sin(x),cos(x)三者的指数作为key
第三次:尽量转化为接口和继承。如果按我原来的思路,我只能把“各小求导部分”用一个接口合了,再各种重写,sin()和cos()的可以用一个继承实现
(五)一些数据
另外,第三次作业的类图如下,自底向上为main,submain——每次剥离除了新的表达式就进入sunmain,它会进行判断、进入加数求导、乘数求导、各小部门求导等行为
Addle类:加数分解、求导;Multle类:乘数分解求导;Qiusin:(sin()求导);Qiucos(cos()求导);Qiux类:x^+1求导;Val类;Valsin类


另外还有一些数据:
第三次的:
各方法:


各类:
第二次的:
各方法:

各类:

面向对象OO第一单元三次作业总结的更多相关文章
- OO第一单元三次作业总结
写在前面 第一单元作业是针对输入的多项式进行格式合法判断,然后进行求导,结果长度优化,最后输出.三次难度递增,不断添加新的需求,总体感觉在实现方面没有多大困难(?),个人主要困扰环节是寻找自己未知bu ...
- OO第一单元
OO第一单元总结 目录 OO第一单元总结 前言 第一次作业 HW1基本思路 UML类图 代码规模 复杂度分析 方法复杂度 分析 类复杂度 分析 优化策略 第二次作业 HW2基本思路 UML类图 代码规 ...
- OO第一单元作业总结
oo第一单元的作业是对多项式的求导.下面就是对三次作业分别进行分析. 第一次作业 分析 第一次作业相对来讲比较简单,甚至不用面向对象的思想都能十分轻松的完成(实际上自己就没有使用),包含的内容只有常数 ...
- 【OO学习】OO第一单元作业总结
OO第一单元作业总结 在第一单元作业中,我们只做了一件事情:求导,对多项式求导,对带三角函数的表达式求导,对有括号嵌套的表达式求导.作业难度依次递增,让我们熟悉面向对象编程方法,开始从面向过程向面向对 ...
- OO第一单元(前四周)作业总结
OO第一单元(前四周)作业总结 OO第一单元(前四周)作业总结要求(第四次作业) 0.前言 本次博客针对的是本人学习Java的第一阶段的三次作业的作业总结 第一次作业的内容是:7-1 计算税率 (20 ...
- 北航OO第一单元作业总结(1.1~1.3)
经过了三次作业之后,OO第一单元告一段落,作为一个蒟蒻,我初步了解了面向对象的编程思想,并将所学内容用于实践. 一.第一次作业 1.架构分析 本次作业需要完成的任务为简单多项式导函数的求解.表达式仅支 ...
- OO第一单元作业总结——表达式求导
OO第一单元作业总结 第一次作业 基于度量分析代码结构 基本算法 第一次作业是简单多项式导函数求解,不需要对输入数据的合法性进行判定, 基本思想是用 (coeff, expo)表示二元组 coeff* ...
- 【作业1.0】OO第一单元作业总结
OO第一单元作业已全部完成,为了使这一单元的作业能够收获更多一点,我回忆起我曾经在计算机组成课设中,经常我们会写一些实验报告,经常以此对实验内容反思总结.在我们开始下一单元的作业之前,我在此对OO第一 ...
- OO第一单元总结
OO第一单元作业总结 一.前言 开学四周,不知不觉已经做了三次OO作业.事实上,每一次作业对我来说都是很大的挑战,需要花费大量的时间和精力来学习. 虽然学得很艰苦,但最后还是连滚带爬地完成了.(好惨一 ...
随机推荐
- 352. Data Stream as Disjoint Intervals (TreeMap, lambda, heapq)
Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...
- 51nod1117(简单huffman tree)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1117 题意:中文题诶- 思路:简单huffman tree ...
- openinstall的免费服务对App推广有哪些帮助?
想在微信中下载 App,需要“点击右上角打开浏览器”,太麻烦: 想深入查看微信分享内容,需要手动打开 App 搜索,不方便: 想给 App 做推广,Android 需要多个渠道人工打包,效率低: .. ...
- Acwing 98-分形之城
98. 分形之城 城市的规划在城市建设中是个大问题. 不幸的是,很多城市在开始建设的时候并没有很好的规划,城市规模扩大之后规划不合理的问题就开始显现. 而这座名为 Fractal 的城市设想了这样 ...
- Java怎么把一个.log文件,以text文件方式打开,显示在桌面
总要有一个开始吧 群里面有一个哥们,问这个问题,索性记录下来, quextion: Java怎么把一个.log文件,以text文件方式打开,显示在桌面 anwser: 这里注意一个问题:拼接路径的时候 ...
- JS 对象的操作方法
第一种: 变量名.style.属性: 第二种: 变量名.style[参数]
- bzoj2662: [BeiJing wc2012]冻结 最短路 建图
好久没有1A题啦♪(^∇^*) 一个sb建图,我居然调样例调了10min 看起来是双向边,其实在建图的时候要当成有向图, 否则他会时间倒流(233) 把每个点裂成k个点,然后把每条边裂成4条边(正向反 ...
- HttpServletRequest 和 HttpServletResponse
Servlet配置方式 全路径匹配 以 / 开始 /a /aa/bb localhost:8080/项目名称/aa/bb 路径匹配 , 前半段匹配 以 / 开始 , 但是以 * 结束 /a/* /* ...
- NET Core 2.0 介绍和使用
NET Core 2.0 特性介绍和使用指南 阅读目录 前言 特性概述 使用指南 .NET Core 2.0和1.0/1.1之间的关系 .NET CORE Rumtime改进 .NET Core SD ...
- restframework安装及APIView分析
一.restframework的安装 方式一:pip3 install djangorestframework 方式二:pycharm图形化界面安装 方式三:pycharm命令行下安装(装在当前工程所 ...