• BUAA_OO_2020_第一单元


    BUAA_OO_2020_第一单元

    Part 1.作业及评测分析

    第一次作业

    类图:


    结构分析:第一次作业只有一个多项式,故我把类的关系分成了多项式类,项类和求导类,多项式类负责处理输入输出,对多项式完成截断处理,将截断的字符串传入项类进行处理,在项内完成对前系数以及指数的读入处理,完成项的构建,构建项之后在多项式类中我才用HashMap存储项,这样可以快速寻找到同类项,完成合并。

    复杂度:


    复杂度分析:在print时模块的设计复杂度极高,由于没有在poly中采用重写toString方法,在多项式类中采用了大量的数据交互和判断,导致模块之间的耦合度高,这是设计上的一次失败。

    评测:

    第一次作业比较简单,评测并没有出现bug,同时因为采取了合并同类项,优先输出正项,对于1和-1的特殊处理等手段,性能比较高,在强测中拿到了满分

    第二次作业

    类图:


    结构分析:第一次作业处理中,将constantx**pow看成了一个整体,在加入了sin(x)和cos(x)之后,这个架构显然显得力不从心,也是因为重新加入了两个因子,我开始对表达式进行了重新的认知,表达式的构成为:项+表达式,而项的结构可以看成因子项。而且第二次作业中没有括号的存在,所以项可以看成基本因子的连乘。

    而基于这些特性,在第二次作页我产生了一个取巧的方法:项与项之间一定是通过加减号来划分,那么我能不能通过将加减号做特殊处理,从而可以直接用Scanner类来处理呢,接下来我罗列了几个表达式,寻找表达式之中加减号的特征,我发现凡是用来区分项的加减号前面不是乘号,所以我首先合并了多个的加减号,之后处理了前面不是乘号的加减号,使用Scanner类直接读取,完成了项的划分,之后在项中,我发现,乘号划分了因子,故技重施,完成了基本因子的划分。

    接下来便是对基本因子的处理,这次我采用了接口的思想,减少了代码的重复性。

    最后将一个项划分为四元组,这次我吸取了上次的教训,在项类中重写了toString方法。

    复杂度:


    这次的输出复杂度明显得到了改善,但是由于在写完之后才想去化简,导致化简这个类的添加比较突兀,也导致其耦合度比较高。

    谈谈化简:

    这次作业的长度有限制,我分析最大项数不会超过50,所以我取巧的采用了三重循环,结构是首先找到具有相同的x**pow的项,将其划分为一个表达式类

    循环结构:

    所有的表达式类

    表达式类中的每一项

    在表达式类中寻找可以化简得项进行处理,直接将被处理项的系数化为0,防止出现循环处理现象

    这样的话,其实仔细分析,发现复杂度如下x(n-x)(n-x),x为表达式类数量,所以可以保证不会出现tle的现象,但是由于循环迭代层数过多,导致复杂度飙升。

    评测:

    这次评测中强测通过了所有的测试点,但是由于小于等于10000被误理解为小于10000,导致边界数据出错,惨遭5刀。

    在互测中,使用了评测机加边缘数据手动评测联合的方法,找到了两个人的bug,而且发现了一个用static方法一main到底的同学,我笃定ta一定会有bug,但是没想到多次评测都没有找出问题数据,也没有采用通读ta的代码的方式寻找bug。

    找到的bug:
    1.爆栈
    2.化简时出错,只处理了一个项,另一项搁置

    第三次作业

    类图:


    结构分析:这次作业中由于迭代结构的产生,导致前两次作业取巧结构的覆灭,在处理输入上我也陷入了困境。

    经过仔细分析表达式发现表达式依旧可以像第二次作业那么想像,只要把表达式类也当作基本因子处理即可解决嵌套问题,但是关键在于,因子的处理。由于不想采用转换为char数组再处理的方法,仔细查看了String的文档,发现了两个极其有用的函数,charAt和subString,采用这两个函数,极大程度上显现出了String类相较于字符数组的优势。同时采用了树结构构造Item(项)类,实现了递归求导。同时也实现了判断WORNG FORMAT和读入处理的一体化。在读入处理时完成了合并同类相,例如:

    x*x*x*x
    sin(x)*sin(x)**2*sin(x)**3
    1*x*2*x**3*sin(x)*cos(x)*sin(x)**2

    实现了这些基本因子的合并,在递归求导的过程中也实现了1,0等特殊结果的化简处理。

    复杂度:


    由于在自己测试的过程中,发现了迭代层数过多导致tle的显现,所以代码经过了几次比较大的修改和重构,导致代码结构面目全非,代码也是越写越难看,在BracketDeal类中,甚至出现了四重判断迭代的丑陋代码,导致复杂度飙升。

    评测:

    这次强测中没有发现问题,但是由于某些tle情况处理仍未达标,在一些多重嵌套的过程中再次出现了tle的现象,而在处理别人代码的时候,采用评测机,但是忽视了空格和制表符的作用,在生成的数据中没有空白字符,漏判了组中一人将正确格式误判为WORNG FORMAT的情况,导致失分。

    Part 2.对比

    在和别人的对比中,显著的几个问题:

    多重迭代判断和多重循环的出现:导致自己的复杂度很高,而且不利于维护;

    在化简时很多情况没有考虑,而在第三次作业中由于采用了递归的结构。很容易导致超时,所以在限制了化简的手脚,大幅删减了化简代码

    几次作业的迭代非常差,每次新作业都需要重构,后瞻性和可拓展性差

    Part 3.感受

    在这几次作业中,对面向对象逐渐有了自己的想法,甚至开始觉得采用c语言或者是一main到底很难实现想要的功能,感受到了面向对象式开发的优点

    同时也认识到了自己的不足,每次作业迭代极差

    也感谢CheckStyle的使用,让我认识到了许多先前存在代码风格问题,也锻炼出了驼峰命名法的使用,在if和for/while的结构也更加美观

  • 相关阅读:
    【机器学习】:梯度提升决策树(GBDT)
    【推荐系统】:LFM算法解析
    【SQL】:内连接,自然连接
    【SQL】:保留小数点后几位(除法)
    Ubuntu 18.04:磁盘读取性能不佳
    skynet超时机制实现
    关于 Spring Boot 中创建对象的疑虑 → @Bean 与 @Component 同时作用同一个类,会怎么样?
    记录不存在则插入,存在则更新 → MySQL 的实现方式有哪些?
    记一次线上问题 → 对 MySQL 的 ON UPDATE CURRENT_TIMESTAMP 的片面认知
    WebSocket
  • 原文地址:https://www.cnblogs.com/lphoebe/p/12516455.html
Copyright © 2020-2023  润新知