OO第一单元总结

 (一)三次作业思路 

    1.1第一次作业 

    第一次作业中的表达式没有括号和三角函数,而且不需要进行格式检查,很容易用正则表达式写出因子和项的一般形式。因此使用正则表达式不断读取因子,对因子的种类(x的幂或是常数)进行判断,存储在hashset中,之后统一求导即可。

    第一次作业的性能方面,只要进行了合并同类项,对筛选以正项作为求导式的第一项,同时进行了合理的省略(以及将x**2写成x*x),基本能得到满分性能分。(没有考虑进行因式分解)。

    在作业过程中,replaceAll和spilt的使用会让处理表达式的过程方便容易很多。

    1.2第二次作业

    第二次作业加入了括号,括号内的表达式和括号一起作为表达式因子(一种因子的种类),同时加入了新的项:sin(x)和cos(x)。

    从第二次作业开始就要使用递归的方法,也有同学在递归处理表达式的过程中直接求导,但我采取先对三角函数换元展开原式合并同类项并记录,之后统一求导的思路。 相比于读取表达式时就求导并开始堆积求导式的方法,我的方法对于括号嵌套层数较多和同类项较多的样例得到的结果更加简洁,性能分更高。

    使用Expressionmap 和 termmap分别记录表达式和项,读取字符串时直接填充termmap,读取完一项之后将termmap的内容通过类内方法转移到expressionmap中。并生成一个新的termmap继续存储下一项的内容。每一项都保存为x^a*y^b*z^c。(y,z分别代表两个三角函数)之后统一求导,思路图如图所示。   

    1.3 第三次作业

    第三次作业三角函数内部可以嵌套任何形式的因子,同类项的出现会减少很多,而且由于sin()内部括号中形式多样,很可能内部也有很多层无法展开的表达式嵌套,最重要的是还有格式检查,因此我放弃了之前先展开合并再求导的思路,采用读取时就求导存储的方法。第三次作业中有很有层嵌套,划分清楚每一层之间的界限很重要,同时吸取上一次作业类存储和方法都区分不够明显的教训,进行了严谨的递归调用。

    总体思路如下(类名和方法名都很清楚,不再注释解释,循环借鉴了正则表达式表示的符号)

    需要的类:Main,Expression,Term,Factor.

      需要的方法:readexpression,readterm,readfactor。返回值都是剩余还未读的字符串

    readexpression分为:readterm, [读加减,readterm]* ,在一个循环结束遇到“)”或字符串为空则合法。

    readterm分为:[读符号]?readfactor [读乘号,readfactor]*。

    readfactor : 检测起始若干字符判断种类,之后 readsin,readcos,readx,readigital,readexpression。

    遇到”(“,去掉左括号后,readexpression。检测返回的字符串是否以“)”开头。

    各类中使用origin和poly两个String存储原式和求导式,以便链式和复合求导。 必须成功的读取如果失败,返回Null,接收到Null也返回Null

    最后在主函数中,接受到返回值为“”,则格式正确输出求导信息,其余接受情况输出WF.

  (二)三次作业问题

    2.1第一次作业 

    第一次作业较为简单,没有遇到什么问题,但由于距开始写作业以来,JAVA也只学习了1个多星期,写起来仍然非常费劲,没有提前了解过JAVA语法在最开始写时感觉完全无从下手,但大海捞针般地看“轮子”时看到了 Pattern, Matcher, replaceAll,Hashmap等“轮子”之后就轻松了很多。

    2.2 第二次作业

    第二次作业中,我对于用什么类存储表达式,项和因子都没有想明白,按照面向过程地思维,想要用统一的类存储term,expression,factor。结果在后面构建代码时给我的前进造成了很大的阻塞,同时对于term,expression的读取方式也没有区分,统一都使用一种方法读取。使我的代码一点层次性也没有,像是星星点点的零件拼出来的,而不是整块整块的模型地拼接的。

    同时生成新的类时,没有搞清楚克隆和引用的区别,以为自己做了克隆其实自己是在做引用,造成了循环读取term时很大的bug。

    最后提交作业也是卡线提交的,当天下午心态出现了很大波动,精神也很不正常,在DDL的压力下已经不能够正常思考了,不仅有我自己本身心态不好的问题,而且还有JAVA的语法基础实在过于薄弱,在debug时进行了很多根本不可能发生的猜想,浪费了很多宝贵的时间,造成了自己越来越着急,效率越来越低。第二次作业本身的难度也很高,对于我一个初学JAVA2星期的人来说是个艰巨的挑战。如果我以前也学过JAVA也许就不会这么慌乱了。

    2.3 第三次作业

    第三次作业的主要问题在于格式检查实在是存在太多细节,我根本记不住,也理解不了指导书,只有中测报错了,我有针对性地去看,才知道:原来这种格式是不支持地呀!。于是保证正确性就用光了所有地免费提交配额。但这次作业我写的思路完整清晰,虽然检查格式交错了很多次,但完成作业的速度还是很快的。

   (三)关于别人的bug

   我对发现别人的Bug这件事无能为力,我三次进入的应该都是A屋(强测最多错1个点),别人的bug本来就少,我也不会搭评测机,屋里面大佬们的代码全都有十几个类,上千行,用着奇奇怪怪的方法,我根本看不懂!看不懂!看不懂!只好自己手动造自己觉得考察点比较全面的样例点,命中率只有5%左右。

   (四)关于重构

    我三次作业都是从头开始写的,重构了两次。虽然在第一次就直接使用第三次的作业结构就能避免重构,但相比起来必然要花费更多的时间,丢失性能分。我认为自己第一次第二次的代码大思路仍然是可取的,确实是我当时能想到的最好的方法。第一次replaceAll"//s"和spilt("*")直接将题目变为分类讨论因子,为当时接触JAVA一星期的我完成作业提供了莫大帮助,第二次直接展开括号的方法第三次必然被三角嵌套和格式检查淘汰,但是不需要优化就能得到很高性能分(被扣了0.2分性能分)。虽然重构,但也是有所得的。

   (五)心得体会

    调整心态是在ddl前debug最重要的事情。但焦虑是人的本能,可以用另外一些人类的本能克服它,例如:吃好吃的。我是个喜欢自己胡思乱想的人,我认为在缓解焦虑的过程中,与人说话同样是缓解焦虑很好的方式。

    不同性质的东西就应该用不同的类,实例存储,将不同的对象归纳并用同一种对象表示容易思路混乱,尤其是当这些对象还含有嵌套关系时。

    如果要新建一个的实例,那么应当注意这个实例是否全身上下在内存中都是新的,如果它需要已有的实例的一些信息,一定要清醒自己做的是直接引用还是克隆,不应该稀里糊涂地就新建不管了。

  

  

posted @ 2021-03-26 18:09  mqacy  阅读(37)  评论(0)    收藏  举报