第一单元博客总结
第一次作业:
第一次作业在写的时候没有充分的经验,保留了此前面向过程的编程的习惯,将全部的方法都放在了主类里面。并且使用正则表达式去匹配表达式的每一个部分,使得匹配表达式非常冗长。
1 Pattern p = Pattern.compile("((\\+|-)?(\\d*\\*)?x\\^(\\+|-)?\\d+|(\\+|-)?\\d*\\*x|" + 2 "(\\+|-)?x|\\*(\\+|-)?\\d+|(\\+|-)?\\d+\\*(\\+|-)?\\d+)(\\*((\\+|-)?" + 3 "(\\d*\\*)?x\\^(\\+|-)?\\d+|(\\+|-)?\\d*\\*x|(\\+|-)?x|(\\+|-)?\\d+))*");
利用 (因子*(因子*)) 的方式去匹配一整个项,这一过程显得非常笨拙,中途不断修改匹配表达式,出现了符号遗漏、缺项等各种问题,这也是我在之后公测和互测环节出现Bug的主要原因。
最终我的第一次作业是通过add1和add2两个方法分别完成常数项和指数的求和或乘积计算,在main里面用一个冗长的while去完成读取表达式和求导。所以这其中有很多的if-else if语句,整个程序的复杂度高,模块耦合度高。
整个程序没有可扩展性,添加新类型的因子非常困难,而且无法处理嵌套,导致了在此后的作业需要完全重写。
在Bug互测环节,我自己的强测成绩很低,并且被hack了多次,但是最终Bug修复的内容非常简单,就是此前所提到的正则匹配表达式的疏忽。
互测中我发现一位同学的代码结构上比较清晰易读,但是命名问题很大,出现了xiang,fuOne这种类名或者变量名。而且虽然他使用了类来处理表达式,但最终依然使用了大量if语句,然后我使用了x*x*x*x*x*x*x*x*x这样简单重复的表达式发现了他的Bug。
第二次作业:
第二次作业增加了对简单三角函数和括号嵌套的求导。第二次作业我的思路是将sin(x)、cos(x)、x做类似的处理,因为他们作为因子的形式非常相似,不同点只有求导部分,所以使用了Key值为三者指数数组的Hashmap,处理起来较为简单,对于括号的嵌套采用递归的方式去处理,但是遗憾的是这次作业我没有去添加各个因子的类,依然是在主类中添加括号匹配,求导等方法,最终用一个两百多行的主类来完成这次作业。
所以复杂度和耦合度依然居高不下。但是此次作业的改进是单独去匹配因子,利用读到的符号的来判断是否到达一个项的结尾。
String factor = "(?<f>\\+|-)?(?<xcs>[xcs](?<exp>\\^(\\+|-)?\\d+)?)|(?<f2>\\+|-)?(?<n>\\d+)";
因此正则匹配表达式精简了许多。
互测环节中我使用了多层括号嵌套的方式成功地找出其他同学的Bug。
在Bug修复环节中我出现了无法读取项的第一个负因子的符号的问题,原因是我每次在读取完一个项以后会跳过下一个符号,修复完后通过了互测和强测所有的Bug点。
第三次作业:
第三次作业允许在三角函数内添加多项式,并且还要判断格式错误。这次作业我将各个因子都变成了类来处理,并且用一个Factor类来保存各类因子。
Trigo类是三角函数,存放指数和三角函数类型。
Power类是幂函数,存放指数。
Nesting类是括号嵌套因子,存放括号内表达式用于递归。
Const类是常数。
Factor类设置了以上四个类的变量,以及代表类型的kind数据。
这使我这次作业写起来快了很多,读取表达式时候只要将因子放入Arraylist<Factor>里面,求导时候再对应因子类型调用需要的方法求导即可。
但是因为我并没有去实现各个因子的求导的接口,所以求导方法的复杂度很高。
另外在判断输入是否合法时我没有掌握应该怎么样更简洁地去判断各类情况,使用大量if去完成判断,导致了这一部分也非常复杂。
所以这两个方法在强测和互测环节均出现了Bug。一个是无法识别sin()这样的格式错误,另一个是求导化简幂指数为1时出现了错误。
我在互测时虽然测出了其他同学的Bug,但是并没有从代码发现其他同学的明显错误,只是测试了一组三角函数的各种嵌套的相对复杂的数据。
总结心得:
1.这三次作业我没有太多内容去实现优化,性能分较低,我认为原因一部分是因为我的结构复杂,没以面向对象的思想去实现任务,所以要简化输出可能也会比较困难。但是第三次作业初步尝试了一下类感觉确实非常简洁明了,所以在最初设计的时候就要注意扩展性,我也需要更多的去练习。
2.讨论区是非常有用的地方,你可以参考一些高手的建议,或者发现有人和你有一样Bug可以相互讨论。