第一单元总结
发布日期:2021-10-24 12:41:39 浏览次数:1 分类:技术文章

本文共 4600 字,大约阅读时间需要 15 分钟。

一、作业分析

  第一次作业

  与后两次作业相比,第一次作业非常简单,仅要求对由常数项和幂函数组成的多项式求导。但由于缺少面向对象编程经验,我在这次作业中栽了不少跟头。

  (1)度量分析

    在第一次作业中,我还没有适应JAVA语言面向对象的coding风格。可以看到,我的第一次作业只有一个主类One,所有方法都堆在一个类中。这也导致了我的程序的各类复杂度都相当爆炸,总之是一次惨痛的教训。

    

     

  (2)bug分析

    首先,最重要的一点:

    不要特判!!

    不要特判!!

    不要特判!!

    由于寒假摸鱼的缘故,我对JAVA的很多功能都不甚了解,这个问题在这次作业中充分暴露出来了。

    

String matchB =                    str.replaceAll("[\\t ]*[\\+-][\\t ]*[\\+-][\\t ]+\\d", "w");            matchB = matchB.replaceAll("[\\+-][\\t ]*[\\+-][\\t ]*[\\+-]", "w");            matchB = matchB.replaceAll("\\d[\\t ]*x", "w");            matchB = matchB.replaceAll("x[\\t ]*\\d", "w");            matchB = matchB.replaceAll("\\^[\\t ]*[\\+-][\\t ]*[\\+-]", "w");            matchB = matchB.replaceAll("\\d[\\t ]+\\d", "w");            matchB = matchB.replaceAll("[\\+-][\\t ]*\\*", "w");            matchB = matchB.replaceAll("x[\\t ]*\\*", "w");            matchB = matchB.replaceAll("(xx)|(\\^[ \\t]*x)", "w");            matchB = matchB.replaceAll("\\^[ \\t]*[\\+-][ \\t]+\\d", "w");            matchB = matchB.replaceAll("\\^[ \\t]*[+-]*[ \\t]*\\d*\\*", "w");            matchB = matchB.replaceAll("[\\t ]", "");            if (matchB.length() == 0) {                matchB = "w";            }            String matchC = matchB.replaceAll("\\*x\\^", "");            String matchD = matchC.replaceAll("\\d\\*x", "1");            String matchE = matchD.replaceAll("[\\+-][\\+-]?(\\d|(x\\^?))", "");            matchE = matchE.replaceAll("x\\^?", "");

    这是我第一次作业checkstyle部分的代码,当时我还不能熟练使用正则表达式来检查代码格式。

    特判最大的弊端就是对编程者提取错误信息的能力提出了很高要求,一旦编程者考虑的错误情况不全,就极易在检查格式这一步上栽跟头。 

    此外,由于第一次作业中采用了朴素的特判处理作为checkstyle的方法,我的这一次作业程序的扩展性极差,第二次作业只能推倒重来,这也需要引以为戒。

   第二次作业

  第二次作业的内容是对包含简单幂函数和简单正余弦函数的导函数的求解,在这次作业中,我将上一次作业的代码推倒重建,代码风格开始逐渐偏向面向对象而不是面向过程。

  (1)度量分析

    在第二次作业中,我开始尝试使用多个类处理不同任务,但是有部分类依旧显得过于臃肿。这是我还没有面向对象化的体现。

    我的整体思路是在CheckStyle类中完成格式检查,在Poly类中完成求导计算和输出,Main类的功能则是整体调度。可以发现,我的思路依旧是将类作为一个大型函数来使用,其本质还是面向过程而非面向对象。各个部分也没有做到高度分工,尤其是Poly类,同时需要完成求导计算、化简和输出这三个任务。这也导致了Poly类的复杂度特别大。

  

   

  (2)bug分析

    我吸取了第一次作业的教训,采用了正则表达式作为checkstyle的工具,在提取项的过程中也将正则表达式作为搜索关键词使用。

Pattern p = Pattern.compile("^[ \\t]*[+-]?[ \\t]*[+-]?[ \\t]*" +                "((([+-]?\\d+)|(x([ \\t]*+\\^[ \\t]*[+-]?\\d+)?)" +                "|(sin[ \\t]*\\([ \\t]*x[ \\t]*\\)" +                "([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +                "|(cos[ \\t]*\\([ \\t]*x[ \\t]*\\)" +                "([ \\t]*\\^[ \\t]*[+-]?\\d+)?))" +                "([ \\t]*\\*[ \\t]*(([+-]?\\d+)" +                "|([ \\t]*x([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +                "|([ \\t]*sin[ \\t]*\\([ \\t]*x[ \\t]*\\)" +                "([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +                "|([ \\t]*cos[ \\t]*\\([ \\t]*x[ \\t]*\\)" +                "([ \\t]*\\^[ \\t]*[+-]?\\d+)?)))*)" +                "([ \\t]*[+-][ \\t]*[+-]?[ \\t]*" +                "((([+-]?\\d+)|(x([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +                "|(sin[ \\t]*\\([ \\t]*x[ \\t]*\\)" +                "([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +                "|(cos[ \\t]*\\([ \\t]*x[ \\t]*\\)" +                "([ \\t]*\\^[ \\t]*[+-]?\\d+)?))" +                "([ \\t]*\\*[ \\t]*(([+-]?\\d+)" +                "|([ \\t]*x([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +                "|([ \\t]*sin[ \\t]*\\([ \\t]*x[ \\t]*\\)" +                "([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +                "|([ \\t]*cos[ \\t]*\\([ \\t]*x[ \\t]*\\)" +                "([ \\t]*\\^[ \\t]*[+-]?\\d+)?)))*))*+[ \\t]*$");

    这是我checkstyle时使用的超大正则,经过实际检验并不会爆栈。大正则的好处是比较直观,缺点则是编写和debug时会比较痛苦,只能说要慎用。

 

private String strin;    private Map
match = new HashMap
(); private Map
result = new HashMap
();

    我新建了两个hashmap变量用来保存项的内容,第一个保存求导前的内容,第二个保存求导结果。这样做的好处是便于合并同类项,可以把项的内容作为保存的关键词,项的系数作为保存的内容。

    我的这次作业中并没有出现bug,但由于我未考虑诸如sin(x)^2+cos(x)^2这类情况的化简,导致我的性能分比较低。

  第三次作业

    第三次作业在前两次作业的基础上加入了嵌套函数的定义,尽管这类嵌套仅限定在正余弦函数中,但这仍给编程带来了相当大的挑战。

  (1)度量分析

    在这次作业中,我使用CheckStyle类检查代码格式,Calculator类完成求导计算,Print类完成化简和输出,Poly类作为存储,Main类整体调度。可以看到,代码复杂度相较前两次有了明显降低。部分类的复杂度较高的原因可能是我定义了比较多的正则表达式变量的原因。

    

    

  (2)bug分析

    我这次作业的bug主要来自于正则表达式的编写错误。由于本次作业的结构与之前有较大差异,我重构了之前的正则表达式,不慎有一处括号写错了地方,导致在checkstyle部分产生了很严重的误判。

二、debug经验

    我debug的主要方法还是人工查bug(不会写评测机的泪),效率很低,但对我个人编程能力有很大的提升。尤其是在阅读代码风格很好的代码时,会让人有眼前一亮的感觉。

    我习惯先顺着别人的思路将他的程序按流程过一遍,从而分析他的程序在哪一步可能会出问题。这种方法对于找bug而言效率很低,但是在阅读学习他人程序时可以排上用场,靠人眼评测机来理解作者想要表达的意图,并将其1转化为自己的知识。

三、反思

    第一单元的三次作业,主要目的是给我们“练手”,逐渐培养面向对象的编程风格。因此,模块化编程就十分重要了,我现在习惯在coding前先理一遍整体思路,将各个部分需要实现的功能规划清楚,在一步步完善各个部分,最后将这些部件“组装”成一个完整的程序。

转载于:https://www.cnblogs.com/DoubleRider/p/10609120.html

转载地址:https://blog.csdn.net/weixin_30784141/article/details/98382711 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:java日期处理总结
下一篇:DVA框架统一处理所有页面的loading状态

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年03月13日 13时13分43秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

hadoop 3.3 一直停留在running wordcount_蛋价持续下跌,今日跌破3.3元大关!深秋季节价格还能反弹吗?... 2021-06-24
的流程图做完后如何保存_2019超火的半永久眉是哪款?做完后我们如何护理?... 2021-06-24
去除logo 高德地图api_深圳品牌logo升级如何保持原型的同时更具创新? 2021-06-24
二重积分转换成极坐标_二重积分转换极坐标r的范围如何确定? 2019-04-21
python中倒背如流_八字基础知识--倒背如流篇 2019-04-21
以太坊地址和公钥_以太坊地址是什么 2019-04-21
linux查看wifi信号命令_linux – 获取WIFI信号强度 – 寻求最佳方式(IOCTL,iwlist(iw)等)... 2019-04-21
npm 不重启 全局安装后_解决修复npm安装全局模块权限的问题 2019-04-21
vs格式化json 不生效_vs code 格式化 json 配置 2019-04-21
go 字符串反序列化成对象数组_Fastjson 1.2.24反序列化漏洞深度分析 2019-04-21
onmessage websocket 收不到信息_WebSocket断开重连解决方案,心跳重连实践 2019-04-21
hibernate mysql 缓存_hibernate和mysql的缓存问题,没辙了! 2019-04-21
abp框架 mysql_ABP框架使用Mysql数据库 2019-04-21
PHP实现 bcrypt,如何使php中的bcrypt和Java中的jbcrypt兼容 2019-04-21
matlab变形监测,基于matlab的变形监测数据处理与分析_毕业设计论文 2019-04-21
电梯运行仿真c语言代码,电梯调度算法模拟(示例代码) 2019-04-21
android组件动态接收数据库,Android开发——fragment中数据传递与刷新UI(更改控件)... 2019-04-21
云麦小米华为体脂秤怎么样_云康宝和华为智能体脂秤对比评测,实际体验告诉你哪款更好... 2019-04-21
linux 条件判断 取非_Linux awk 系列文章之 awk 多重条件判断 2019-04-21
c语言中如何将字符串的元素一个一个取出_C语言中常用的字符串操作函数 2019-04-21