BUAA_2020_OO_第一单元总结

三次做业,三次成长正则表达式

第一次做业——幂函数求导总结

做业思路和心得

第一次做业的要求只有x的指数这样的幂函数加减组成表达式,对表达式进行求导,并且没有格式错误的检查,因此难度感受还不是很高。不过因为我寒假的preview做业还有两个task没有作完,因此我感受本身对语法和字符串处理等方面还不是很熟练。所以,虽然看起来第一次做业难度不高,可是我仍然十分认真地对待它,把它看成巩固本身基础的一次机会(以后的做业就没机会巩固基础了
进入正题,第一次做业因为只有一种幂函数,因此个人思路也比较简单:直接用TreeMap存储x的系数和指数,其中以指数做为Key以便于合并同类项。求导规则也很简单,只需将TreeMap里的每一个元素取出来系数乘以指数输出为系数,指数-1做为新指数就完成了求导过程。
第一次做业让我调试了好久的地方是用正则表达式读入输入并进行分割,因为我对正则表达式掌握不熟练,期间查阅了众多资料和助教发的教程,最终在不断的摸索和尝试下,我写出了那个分割输入的正则表达式,写出正则后,后面的处理就显得简单不少了。第一次做业让我对正则的了解更深刻一步。编程

程序结构分析

  • UML分析
    第一次做业因为对面向对象思想理解不够,同时做业结构较简单,因此我在第一次做业只有一个Main类,有131行,类图也只有一个类,就不上图了。(之后要是再这么写就要次次重构了呢!数据结构

  • 复杂度分析

    从分析表中能够看出,个人第一次做业中的getInf方法的设计复杂度和圈复杂度都较高,回归代码本人确实发现这个方法中if-else的结构嵌套较多且逻辑较复杂,同时因为它是第一次做业提取因子的主要方法,因此其被其余方法调用的次数也较多,致使其和其余方法的耦合度也较高,设计复杂度太高,致使其扩展性和复用性较差。架构

hack与被hack

第一次做业给了我惨痛的教训。我在强测中只得了18分,为何呢?缘由就在于我在优化过程当中对正数的输出我误觉得只会在开头,因而把+省略了(大概脑子一抽,捂脸.jpg),致使了我在强测中大量的输出格式错误,也就致使了我没有机会进入互测,第一次做业中也就没有获得什么hack别人的经验。函数

第二次做业——幂函数加三角函数求导

做业思路和心得

第二次做业除了幂函数还外加了三角函数,不过好在三角函数内部只能是x,这样全部输入的形式也最终能够化为三种:xa,sin(x)b,cos(x)^c。那么这样的话,我依旧能够沿用第一次做业的整体思路,即用TreeMap进行输入因子的存储,只不过此次的Key要新建一个类来存储三个因子各自的指数,求导方法的话也只需分红六类便可(三种因子随意组合——6种)。此次惟一与上一次不一样的是多了WF判断。那个人思路是,既然错误那么多,找也找不全,不如构造正确的表达式的正则表达式,输入的能匹配,那就OK,匹配不上那就确定是WF。这种思路避免了WF的漏判。
但因为此次输入复杂了一些,同时还要构造正确的正则表达式来判断格式,让我在第一次做业中学习到的正则表达式知识又捉襟见肘了。因而我在第二次做业期间,又花了一部分时间去学习更高级的正则表达式用法,最终第二次做业也是用正则表达式的形式来读取输入,判断格式,效果还不错。作完第二次做业,我感受本身对正则表达式又有了更深一层的理解。第一次做业结束感受本身正则表达式掌握的不错了,第二次做业结束让我感受本身对正则表达式还有不少须要学习的地方,由于越是深刻越是发现正则表达式的高级用法还有不少我所不知道的。我要在从此的学习中进一步深刻了解正则表达式的用法和原理。性能

程序结构分析

  • UML分析

    第二次做业中我是在第一次做业的基础上添加了三个类用来存储三个因子做为一个总体信息单位的信息。看起来有了一点OO的意味,可是写完三次做业回头来看,本人第二次做业使用的类并非为了构建OO的思想架构而是在无可奈何的状况下为了沿袭第一次做业的TreeMap思想,不得已加入几个存储信息的类。那些类的做用实质上仅仅封装了数据,相似于C语言的结构体,实际上并无什么架构上的改变,这是我须要在从此的设计中进行改进的。类的做用不该仅仅局限于封装数据,而是发挥它们真正强大的功能。学习

  • 复杂度分析


    第二次做业的总体结构较第一次做业明显复杂了许多,因此总体复杂度也有所上升。图中所示个人main方法基本复杂度是最高的,其余复杂度也很高,缘由在于我给TreeMap的排序接口comparator进行了重写,由于Key是我本身定义的类。这部分重写我须要对自定义类里的三个指数依次进行比较判断,致使if-else结构不少,复杂度提高。以后查资料我发现这个方法重写也能够在自定义类内进行,这样能够大大下降main方法的复杂度,让main方法看起来更简洁。
    除了main方法,还有几个方法复杂度较高。Stringprocess、display、judgekind等方法复杂度都较高,这就是我在UML分析里所说的,我在第二次做业中新建的几个类并无帮助我下降总体结构的复杂度也没有下降耦合度,仅仅是封装了数据,因此复杂度高的方法内部仍然有许多if-else判断和过程式的残留痕迹。这些都须要我在之后的学习中尽力克服,养成良好的习惯和思想。测试

hack与被hack

我在第二次做业中终于第一次体会了互测的快(刺)乐(激)。我第一次有机会看到别人的代码,我抱着学习的心态,把每一份代码都下载下来看一看。可是我发现除了几份架构清晰、逻辑至少能看明白的代码外,其余的真的很难理解,也不知道他想干什么。因此,我决定不用彻底看懂代码,直接上测试数据。
测试方面,我其实不习惯于使用本身搭建的评测机,由于我以为那样覆盖性很差,并且重复数据较多,效率不高。我更喜欢本身根据指导书,本身手动构造一些特殊易错数据进行本身的测试和互测的用例。实践证实,互测中我使用的都是我本身在写代码的时候本身积累下来测试本身程序的用例,效果还能够,至少每组数据都至少能hack到一个房间内成员。
第二次做业我本身程序的bug又是出在了化简的过程,又是在某一种状况下少输出了一个+(再一再二,不能……优化

小提示(给本身之后准备的

JAVA语言中类是引用类型的,因此当类做为参数传递时,对参数的操做也会对外部的类变量产生改变。因此在相对类的部分进行操做并产生新的类时,必定要进行clone或是copy。在本次做业中我就使用了这种方法来进行操做,先来看代码:网站

```

public static Inf CopyInf(Inf a) {

    Inf newInf = new Inf(null, null);

    if (a.getKey().getXindex() != null) {

        newInf.setKeyX(new BigInteger(a.getKey().getXindex().toString()));

    }

    if (a.getKey().getSinindex() != null) {

        newInf.setKeySin(new BigInteger(a.getKey().getSinindex().toString()));

    }

    if (a.getKey().getCosindex() != null) {

        newInf.setKeyCos(new BigInteger(a.getKey().getCosindex().toString()));

    }

    if (a.getCof() != null) {

        newInf.setCof(a.getCof());

    }

    return newInf;

}```

这段代码是我在进行乘法求导时,对其中一个因子进行求导,剩余的不变时,要进行这个方法的调用,进行信息的复制。可是以后我查资料发现,JAVA中的基本类型(int,String等)和基本类型包装类(Integer,BigInteger等)这两类变量是不会致使内部信息变化的,因此其实在我这个第二次做业中,不进行信息复制也是能够的。不过我在这里就是想给之后的本身和看到这篇文章的读者们提个醒,在对同一个类进行屡次操做且每次操做都要基于原始数据的状况下,不要忘记进行clone或是copy。否则这种隐蔽的错误真就写bug一分钟,debug到两点钟。

第三次做业——嵌套表达式求导

做业思路和心得

第三次做业较以前两次难度再次提高。我感受难度最大的部分就是输入的读取和WF的判断。因为增长了嵌套表达式,整个输入的结构变得十分灵活而复杂。表达式里会有因子,因子里又会有表达式,这样对输入的处理是极大的困难。
为了提升性能,我采用了WF判断和输入的分析读取合在一块儿进行。先使用第二次做业中的Stringprocess方法将多余的符号去掉,再从头开始循环读取。读取的时候,判断括号数量是否匹配。其他WF在读取以前先遍历一遍字符串进行判断。
读取好各个因子后,就能够创建表达式树,建好后就按链式求导法则,对整棵树进行求导,求导后输出便可。在此,我要提一下个人初版方法,就是将求导方法交给每一个类内部本身管理,每一个类内部也有本身的数据,这样,我最开始的想法是让类本身调用各自的方法,递归求导。可是我实现后发现,这样复杂度和空白数据量都太大了,并且逻辑也不清晰,就放弃了这个方法。最后选择了建树的方法。因为本身的数据结构基础也不够扎实,在学习创建表达式树的期间也费了好一番力气,查阅了大量网站资料。因此,我要告诉本身,基础要打好呀!(相信如今说为时也还不晚

程序结构分析

  • UML分析

    因为此次结构较复杂,因此为了减小代码量,我使用factor做为四种因子的父类,减小重复代码。此外,因为个人StringProcess和WF都是从新遍历了输入,因此与其余模块关联不大,我以为这让个人这两个模块提升了可移植性和重用性,因此这两个模块是我较为满意的模块。表达式树的那几个模块,因为以前我对树的掌握不牢,致使这部分建树没有什么思路上的创新,按照固有方法和套路进行编写。也致使了以后输出的化简很难操做。

  • 复杂度分析



    因为程序复杂度的提高,方法的数量也大幅度提高,方法的复杂度却是没什么巨大的增长。我分析缘由在于我进行重构,选择表达式树以后,以前的一些复杂的大方法被我拆解为各个小方法放到类中,本身管理。因此方法的数量增长了,可是复杂度没什么暴增。

hack与被hack

第三次做业我本身的程序的bug主要出在WF判断这部分,我在本地本身测试时,就发现不少不应判WF的判成了WF,该判WF的却输出告终果。我对这些问题对程序打了不少个补丁,可是在强测和互测中仍是发现了几个本身没有发现的点,致使了错误。这让我明白了本身构造数据的时候的方法有问题,我会在从此的做业的构造数据的过程当中,注意改正,争取获得更好的测试效果。
在第三次互测中,随着程序体积的膨胀,彻底阅读懂代码变得更加不现实了,因此我依旧采用第二次做业的方法。在互测中提交本身本地测试出现问题的用例,同时想想别的经常使用方法会出现什么问题。效果也仍是不错,不多有无效用例,大多都是找到了同组人员的bug的。

总体感悟思考

从寒假的一无所知到preview的有所了解到unit1的稍有理解,能够说这门课程让我一步步地走进了面向对象编程的世界。这一级级台阶也要感谢课程组的老师和助教们。 可是回头看来本身的三次做业,发现面向对象的一些经常使用的pattern尚未灵活运用,一些经常使用的思想也尚未深刻理解。这些都须要我在从此的课程中努力学习,尽力理解的东西。 我也在第一单元做业的历练中,发现了一个适合本身的写测结合的方式。我喜欢每写完一部分就认认真真、仔仔细细地测试一遍这一部分的功能是否正确。直到在我看来,这部分写完的代码功能上彻底没有问题我才会继续写下去。这样我感受虽然用时较多,可是写起来让我本身感受更加安心,同时也让debug的难度有所减少。我感受是适合我本身的编写方法。我会在从此的做业中,继续使用这种方法,但愿可以取得良好的效果。

相关文章
相关标签/搜索