第一单元OO作业总结

第一单元OO作业总结

Applying Creational Pattern

​ 前三次的OO作业围绕表达式求导展开,对表达式定义不断丰富,最后甚至到了循环定义也是够狠了,彻底打消了我使用不支持平衡组特性的JAVA正则的念头。

​ 总的来说,我觉得几次的作业设计模式中有两个值得总结的要点,如果一开始就对这两个要点概念清晰的话做起来会轻松很多,不至于像我一样次次重构。

  • 输入处理
  • 究竟什么是因子?

输入处理

​ 这次的输入处理主要有两个主要思路。第一是使用正则表达式,通过从底至顶定义表达式中的各个部分(带符号整数、指数、因子、项、表达式),然后直接使用定义的正则来输入处理。以下是我第二次作业的正则定义代码:

public static final String signedInt = "([-+]?\\d+)";
public static final String exponent = "(\\s*\\^\\s*" + signedInt + ")";
public static final String powerFunc = "(x" + exponent + "?)";
public static final String tagFunc = "((sin|cos)\\s*\\(\\s*x\\s*\\)" + exponent + "?)";
public static final String factor = 
    "(" + signedInt + "|" + powerFunc + "|" + tagFunc + ")";
public static final String item = 
    "(?<=([-+]|^)\\s*)[-+]?\\s*" + factor + "(\\s*\\*\\s*" + factor + ")*+";
public static final String expression = 
    "^\\s*[-+]?\\s*" + item + "(\\s*[-+]\\s*" + item + ")*+\\s*$";
public static final String op = "[-+]";

​ 第二个思路就是解析字符串。这个想法应该是很常见的,第一次作业也有很多人都这么干了,就类似于大一C里面手工处理字符串。

​ 这两个思路孰好孰坏很难下定论,说实话我第一次想到解析字符串的方法是拒绝的,解析字符串怎么面向对象嘛?你不要搞我啊!要我回头写手工字符串的代码可不行,时代不能倒退的呀!

​ 但事实证明我还是真香了,首先第一,第三次作业JAVA的正则因为不支持平衡组特性,完全就写不出一个能匹配对应括号的正则,直接歇菜。第二,解析字符串也完全可以以面向对象的方式进行,读JAVA源码的时候发现,JAVA的Integer类有parseInt方法,Double类有parseDoule方法,都是对字符串进行解析将第一个符合要求的子串转换为本类的一个实例的静态方法,这次作业完全也可以仿照这么设计,将对字符串的解析过程分成几个子过程封装在Exp类、Item类和Factor类,也可以完美实现“一个类就做一个类的事”

究竟什么是因子?

​ 这个问题还可以这么问,究竟什么是项?究竟什么是表达式?仔细想一想自己在对类进行设计的时候有没有清楚地辨析过这几个概念。这三次作业的重构过程我很多代码都可以直接复用也是受益于我这三个概念从定下来就没变,所以代码的整体结构不需要变动。

​ 这应该属于类设计的一个环节,当你对自己的类有明确的定义的时候,你会自然联想到它应该有的一些方法和应该满足的一些借口。举一个简单例子,我的表达式定义是”{Item|Item != 0}“,一个项(值不为0)的集合,那么他需要实现什么方法呢?答案就很显然了,一个append()方法来往集合里添加元素(当这个元素是0的时候不添加),一个merge()方法来求集合的并集(直接对另一个集合每个元素调用一遍append()方法就好),重写一个equals()方法来判断两个集合是否相等,等等。当然因为是作业,有固定的需求和使用场景,所以我们通过定义联想到的方法可能并不是都用得上,但是这个方法是很有用的!可以让自己设计更高效框架,更完备。

基于度量分析自己的程序结构

使用Idea插件MetricsReloaded和UML support。

ev(G)基本复杂度是用来衡量程序非结构化程度的.

Iv(G)模块设计复杂度是用来衡量模块判定结构,即模块和其他模块的调用关系。

v(G)是用来衡量一个模块判定结构的复杂程度,数量上表现为独立路径的条数。

第一次作业:

第二次作业:

第三次作业:

优点:设计比较独立,各个类之间耦合度不高。

缺点:部分方法的时间复杂度实在是让人难以接受。因此互测也吃了两次T:<

分析bug

​ 这次几次作业我自己的bug主要出在对程序性能的优化上,在合并同类项、优化表达式长度的时候都偷了懒一直在用暴力遍历,甚至最后一次作业连往类里头加一些访问器方法都没加,直接从调用toString()来获取类的信息,比如我一个项的系数的signum()函数是直接toString()然后看字符串首字符是不是‘-’。最后导致TLE,我真傻,真的。

​ 互测的时候其他人的bug主要是出在输入判断这块,就是条件判断的不够仔细导致的。

posted @ 2019-03-23 21:21 ChenL 阅读(...) 评论(...) 编辑 收藏