前言:题目集一主要涉及了java程序的基本结构,编译器的基本使用方法,基本语法。题目7-8初次介绍了类。题目数量比较少,难度较低,主要是让我们适应了Java的编码习惯。
题目集二更进一步设计了字符串,数组的操作,3,4,5题层层递进为我们引入了方法。题目中设计的方法声明让我初次感受到了面向对象编程。这个题目集题目数量依然比较少,难度略有提高,让我熟悉了方法有关的各种语法。
题目集三真正涉及到了类的设计,1,2题抛砖引玉让我体会到了类设计的思路,第三题则需要完全自己设计类。这个题目集题目数量较少,但是工作量不小,难度比较大。这个题目集让我学会通过合理的设计类来简化逻辑,通过重构来适应新需求,最重要的———利用不熟悉的知识来解决一定规模的问题,并且合理渐进的使用他们来避免大量未知错误在一开始爆发导致延误开发。
程序需要判断三角形类型,要求能够识别非三角形,等腰三角形,等边三角形,等腰直角三角形,直角三角形,一般三角形的情况。难点在于要捋清各种三角形的逻辑包含关系,判断三角形种类要尽可能具体,这对逻辑有一定要求,写出优雅健壮的代码是比较有挑战性的。
我的方法是,先利用java提供的排序方法将三边的长度排序,快速识别斜边(最长的边)。先判断是否为合法的三角形,再依次判断是否为等边三角形,等腰直角三角形,直角三角形,等腰三角形。即在判断出构成三角形后,从具体到广泛的判断三角形。
计算机处理浮点数会产生误差,在计算勾股数时判断浮点数之间的等量关系不能直接用”==“,而应该设置误差,将大小差别误差范围内的视为等于。设置误差的过程中即要保证不会漏判,也要保证不能错判,误差的大小要通过对具体的情况进行具体的分析来设定。此外大量的if语句让代码难以理解更难以修改,即使写了大量备注,可备注也要随着代码的更新而更新大大的增加了工作量。所以代码书写的过程中规避的繁杂的实现是避免bug的关键。代码整体的复杂度还是偏高的。
为了增强代码的可读性可以通过实现多个判断三角形类型的方法,每种方法之对应唯一一种三角形,虽然效率上有牺牲但是却减少了if增强了可读性。还有一种方案是对三角形的各种性质(两边或三边相等,直角)设置对应的枚举,通过检查枚举来判断三角形类型,这样if语句的可读性会提高。或者生成一颗逻辑上的树,每个节点都代表一种三角形,逻辑上是子概念的三角形是下相应三角形的子节点,通过由广泛到具体的检查,当一个节点的所有父节点被满足的时候该节点被满足。这样同样避免使用大量带&&复杂条件增强可读性,也具有良好的扩展性。
题目要求输出某一日期的下一天,并给出了需要实现的方法包括,判断闰年,判断日期合法性,求下一天。这题涉及很多特殊情况,关键是通过对这些特殊情况进行分析,厘定先后判断顺序,用最少的判断来解决问题。
我的方法是先判断日期是否合法(包括闰年和平年)再直接对日加一,再判断日期是否变得不合法,如果变得不合法代表日期因该变成下个月一号,再判断月是否合法,如果变得不合法则日期因该为下一年第一天。通过这样的判断日期是否因为加一天这个操作变得不合法,来一步一步改变日期最终得到下一天,规避了判断闰年平年和每个月不同天数的复杂判断,而是反复利用日期是否合法来一步一步得到结果大大减少了逻辑复杂度。
判断闰年的情况比较复杂,如果直接判断闰年,那么涉及的条件比较多,复杂的代码是bug的温床。在这里我选择不去判断是否为闰年,而是去判断是否不是平年,结果代码大大的变简洁了给我后来的debug工作带来了很多方便。很多正面判断比较难的条件,可以考虑通过判断反例来解决。合理的利用数组来代替switch是非常好的做法,让数组的下标带有意义(比如代表月份)也是非常优雅的。
利用数组来储存每个月最大天数从而规避switch来判断日期合法性,也可以准备两个数组分别代表闰年和平年的天数,用枚举来代表闰年和平年,可以大大增强代码的可读性,利用枚举来代替下标,让下标具有意义也是值得尝试的做法.
题目要求程序求出某一天的前n天,并自己设计类来处理。同样涉及日期处理关于每月最大天数的数组,和判断日期合法性以及求闰年,这些部分大体上可以直接使用7-4的代码。
我的方法是将7-4求下一天的代码改写成求前一天,逻辑基本不变,日期先见一再判断日期是否合法,如果不合法,则日期变为月份减一的最后一天,再判断日期是否合法,如不合法则变为上一年最后一天。重复n次,如果n为负数则直接求下一天重复n‘的绝对值次。
相对于下个月第一天,上个月最后一天更具有不确定性,搞不好会导致储存月份最大日的数组越界,适当的为数组留白,是避免bug选择之一。虽然现在并不那么强调软件的效率,而是重视开发速度。但是这种会提升复杂度的算法应该在细致的研判数据再谨慎的使用,或者尽量避免。
实现求前n天改为求前一天n次虽然极大的利用了已有的代码,但是却将原来常数复杂度的算法变成了复杂度n的算法,这种操作是有风险的,在数据比较大的情况下可能会超时,导致软件质量不合格。通过把n超过一年的部分直接计算,再把超过一月的部分直接计算,甚至把超过400年的部分一次性计算来控制n的大小,管理复杂度.保证软件质量。
题目要求实现一个日期类并给出了类图,根据类图按图索骥并且合理的利用之前题目的代码,很快便得到结果。
通过改变返回值和参数利用编译器功能自动生成属性,来简化编码过程。
通过体会和实现类图,我对类中各个方法的耦合和属性的设置有了粗略的体验,对于方法会用到的数据,而对类没有意义的可以选择将其作用域限制在方法内部以简化类的签名。方法只能严格实现方法名所代表的功能,类的属性的和方法的设置最好符合直觉。通过方法间的调用来简化逻辑。
区分一个字段应该是类所有的还是对象所有的,区分的结果因该符合直觉,比如储存每月最大日期的数组因该属于类,设置成静态。这样既可以节约空间也更符合直觉。
题目要求对幂函数多项式进行求导,幂函数有多种省略写法,研判这写发并且进行求导是难点所在。
我的方法是利用正则表达式"[+-]?[0-9]*[*]?x(?:[\\^][+-]?[0-9]*)?"来提取所有带x的项,只有带x的项需要求导。对于每一项用Pattern来分别提取每一项开首的数字和结尾的数字,如果提取不到就代表是省略的写法,结果就是1或者-1.再对系数指数进行计算,通过对计算后的值进行研判来进行项的输出。最后去掉开首的+得到结果。
通过把一个大问题转化为小问题,来解决问题有时候会有奇效。关键是抓住问题不变的地方。对于每个需要求导的项必然有x通过这一点就可以写出提取所有项的正则表达式。此外每一项分开求导再拼接,大大简化了问题,通过最后1步去除开头的+,避免了讨论首项也简化了解决方案。处理问题的时候相应的条件对应相应的部分也是否关键,对于系数的条件判断之影响系数部分,而指数部分则影响是否结果中含x以及是否有显式的指数。这样降低不同代码块之间的耦合,给我debug和重构带来了很多方便。
题目中的正则表达式之并不能完全保证提取出正确的项,没有体现符号和系数之间的逻辑关系,这是非常大的隐患。每一次用循环中字符串的覆盖让声明和内容显得臃肿,利用list生成待处理的项串,再一次性处理拼接,把读取和处理分开来,避免一个代码块过于复杂影响程序的可读性和维护性。
原文:https://www.cnblogs.com/slsj/p/14617490.html