一.问题回顾与基本设计思路

三次作业依次是多项式表达式求导,多项式、三角函数混合求导,基于三角函数和多项式的嵌套表达式求导。

第一次作业想法很简单,根据指导书,我们可以发现表达式是由各个项与项之间的运算符(+,-)组成的,而每个项是由因子与因子间的运算符(*)组成的。对于首项和项的首个因子可能会出现特殊情况。

因此,我认为可以用面向对象的思想来解决这个问题。对象一共有两类,第一类是项,第二类是因子。具体实现如下:

1.读入,并构造一个合法ascii码数组,对于合法的字符char,legal['char']=1,之后扫描表达式,判断是否有非法字符。

2.判断表达式第一个非空格或制表符是否为+或-,若否,则将表达式接在"+"后。

3.构造正则表达式,读取项与项的前置运算符。

4.对于每个项,构造正则表达式读取各因子并存储其指数和系数,这时,对于每个项,可以运算得到唯一的系数与指数。

5.求导并输出。

而第二次作业是与第一次作业类似的,每个项可以表示为系数*sin(x)^指数*cos(x)^指数*x^指数,完全在第一次作业上增写。

第三次作业是增加了表达式因子,定义(表达式)为因子,并规定sin或cos括号内可以为因子,其余要求几乎一致。这是一个递归定义,很自然的我们想到了递归下降法。

在这里,我发现我掌握的正则表达式不能够直接处理这种情况了,联想到数据结构所学习的堆栈,我采取了在第二次作业基础上加入堆栈的写法。

首先构建有限状态机来提取项,这里实际上是使用的是下推自动机。首先先确定几个状态分别表示起始状态,中间状态和结束态,并加入堆栈,当空栈push或者结束栈不空时判为Wrong Format,否则,将该子串作为一个项传入因子处理的状态机。

之后,对于项,同样使用堆栈和状态机,根据括号匹配以及括号外'*'来找出每个因子。

在处理因子时,使用了正则表达式,匹配合法整数,x^n,sin,cos,当遇到sin或cos时,使用堆栈找出其作用的串,去掉首尾括号判断是否为表达式因子,如果均无法匹配,判断是否为表达式因子。

求导亦需要抓取项、因子的步骤,所以将上述部分写作几个类进行复用。

对于求导,链式法则可以简单地用递归处理。我们定义f为一个函数,其因变量为字符串str,则对于函数f(str)求导可以表示为str'*f'(str),进行递归处理,当str为一个合法整数或者是x^n形式时,就可以完成最后一步求导,结束递归。

在这里我对于判断表达式合法与求导进行了保守的处理,没有一边判断一边求导而是先完整判断表达式再求导,这样的好处是避免了边判断边求导是为防止wrong format而不得不存储所有待输出结果,但是会消耗更多的时间。

优化只写了最基本的化简,我觉得可以加上将多重嵌套括号进行化简。

二.类图绘制

第一次作业

第二次作业

第三次作业

三.bug

第一次最为惨烈,有一个重大的bug,是因为我优化时规定当系数为0则不输出,但是忽略了所有项系数均为0时要输出0。

第二次主要是爆栈问题。

第三次是在递归底,在因子类中利用正则表达式判断时有误,使得当首项首因子有前置空白符时会误判wrong format以及爆栈问题。

四.总结与感悟

这三次作业让我粗略认识了什么是面向对象,学会用对象的观点思考问题。第一次作业我依然不太具备面向对象的观点,代码更像是函数较多的面向过程代码,第二次在第一次的基础上将不同层次的对象隔离开分级处理。第三次我认为已经是一个面向对象风格比较显著的代码了,可是在代码复用,也就是继承上依然有所欠缺。

oo第一次博客-三次表达式求导的总结与反思的更多相关文章

  1. OO第一次博客作业

    OO第一次博客作业 一.三次作业的bug反省 1.自己发现别人的问题 (1)输入处理的问题,比如第一次作业,主要就是处理输入的字符串,然后有同学的正则表达式有问题,则对于一些错误输入就不能正确判断. ...

  2. oo 第一次博客作业

    oo 第一次博客作业 早在大一就听说了oo的各种传奇故事,大二下学期终于也开始了我的oo之旅. 基于度量来分析自己的程序结构 第一次作业 类图分析 耦合度分析 可以看出在第一次作业中,我的耦合度非常高 ...

  3. OO第一次博客

    过去的三周里我们完成了表达式求导的程序设计与构造.表达式求导程序,大致思路是实现一个表达式类,支持表达式的输入.求导运算和输出功能.可能的话,还可以增加表达式的化简方法,从而得到更高质量的输出结果.总 ...

  4. OO第一次博客作业--第一单元总结

    OO第一单元总结 面向对象设计与构造的第一单元,对“面向对象”的概念还根本不理解不熟悉,只觉得需要“分模块”,但不知道怎么分,分多少模块,怎么根据需要的模块的功能建立类.学习的进度又太慢,根本跟不上出 ...

  5. OO第一次博客总结

    虽然早在开学之前就已耳闻过OO这门课的威力,也在寒假自学了一些java的语法,但在真正面对OO这样的工程训练时才发现寒假所学的那点语法简直不值一提,也深刻的感受到在这个过程中自己的提升确实很快,毕竟d ...

  6. 2019年北航OO第一次博客总结

    一.基于度量对程序结构的分析 1. 第一次作业 1.1 基于类的分析的度量 首先,基于类的属性个数,方法个数,每个方法的规模,每个方法的控制分支数目,类总代码规模等特征对本次作业的结构进行分析. 1. ...

  7. OO第一次博客作业(第一单元总结)

    Q:菜是绿的,鸡是黄的,那菜鸡是什么颜色的? A:红的,强测全WA了,能不红么. 菜不菜的问题先不说了,认真研究一下这次的题目,以及WA的原因吧. 程序结构简析 三次实验的核心结构都是差不多 第一次的 ...

  8. 始入OO课程的殿堂,初识面向对象的奥妙——OO第一次博客总结

    当我满怀期待叩开OO的大门,却发现宝藏藏在层层阻难之后 第一次作业 1.度量分析 >关于第一次作业的metrics图分析没有出现标红的McCabe Cyclomatic Complexity或者 ...

  9. OO第一次博客作业总结反思

    使用了masteruml插件来生成类图和metrics插件分析代码 第一次作业 1.UML类图 >在第一次作业中,使用了两个类,代码中有没有使用的变量与函数,为平衡两个类的内容,我将输出函数放在 ...

随机推荐

  1. 《openssl编程》:第一章基础知识

    第一章 基础知识 1.1 对称算法 对称算法使用一个密钥.给定一个明文和一个密钥,加密产生密文,其长度和明文大致相同.解密时,使用读密钥与加密密钥相同. 对称算法主要有四种加密模式: (1) 电子密码 ...

  2. Identity角色管理三(编辑角色)

    因只有角色名能修改故继续使用创建角色的视图模型 using System.ComponentModel; using System.ComponentModel.DataAnnotations; na ...

  3. AntDesign VUE:上传组件自定义限制的两种方式(Boolean、Promise)

    AntD上传组件 AntDesign VUE文档 第一种方式 beforeUpload(file) { let isLt = true if (filesSize) { isLt = file.siz ...

  4. 使用easyui进行上左右布局

    在后台管理系统开发的过程中,上左右的布局是最常见的页面布局方式,现在我们来看看使用easyui这个jquery前端框架如何快速搭建一个可用的页面框架. 1.在页面中引入easyui所需的文件 1 &l ...

  5. Docker Compose 实践及梳理

    Docker Compose 可以实现 Docker 容器集群的编排,可以通过 docker-compose.yml 文件,定义我们的服务及其需要的依赖,轻松地运行在测试.生产等环境 文档 Produ ...

  6. Spring Boot 入门系列(二十八) JPA 的实体映射关系,一对一,一对多,多对多关系映射!

    前面讲了Spring Boot 使用 JPA,实现JPA 的增.删.改.查的功能,同时也介绍了JPA的一些查询,自定义SQL查询等使用.JPA使用非常简单,功能非常强大的ORM框架,无需任何数据访问层 ...

  7. Vue3 父组件调用子组件的方法

    Vue3 父组件调用子组件的方法 // 父组件 <template> <div> 父页面 <son-com ref="sonRef"/> < ...

  8. request,response统一编码

    方法:统一使用编码(例如UTF-8编码)解决session或jsp等各种值传递时的中文乱码问题 request.setCharacterEncoding("UTF-8"); res ...

  9. Linux系列(34) - yum源文件(1)

    yum源文件各参数含义 在[/etc/yum.repos.d/]目录中,默认有4个yum源文件,其中[CentOS-Linux-BaseOS.repo]是基本yum源文件,如果我们能上网,那它是默认生 ...

  10. web 阶段的一些简答题

    1.jsp 9个隐含对象 2. jsp 4大域对象 3.mybatis 中 #{} %{ } 的区别于联系 4. Servlet容器默认是采用单实例多线程的方式处理多个请求的: 5.Cookie 与S ...