这里作为(II)的续篇,继续距离 复杂的嵌套if else 的处理。 为了保持篇幅不会太长,所以截断了,以一篇新的文章形式给出。
化简复杂的if else语句,基本的手段
第二个例子,比较复杂一点,给定一个日期,即年 月 日,让你给出下一天的表述。即2000-1-1 ==》 2000-1-2, 2000-1-31==》2000-2-1 2000-12-31==》2001-1-1
这里简化了一些,给各位一些看代码的耐心。只给出月 日, 然后二月固定为28天。
int nextdate(int month, int day) { if (day >= 28) // 如果是一个月的最后一天 { if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { if (day >= 31) { // 这个月的最后一天, 需要同时调整 月 日 day = 1; month += 1; if (month > 12) // 一年的最后一天,需要同时调整年 月 日 { month = 1; } } else { day += 1; } } else if (month == 2) { // 非闰年28号是2月的最后一天 day = 1; month += 1; } else if (month == 4 || month == 6 || month == 9 || month == 11) { if (day >= 30) // 是30号 { day = 1; month += 1; } else { day += 1; } } } else // 如果不是一个月的最后一天,则day直接加1 day += 1; return month * 100 + day; // 计算出明天的日期 }
程序的设计聊完了,先做个简单的重构。
int nextdate(int month, int day) { if (day < 28) {// 如果不是一个月的最后一天,则day直接加1 day += 1; return month * 100 + day; // 计算出明天的日期 } if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { if (day >= 31) { // 这个月的最后一天, 需要同时调整 月 日 day = 1; month += 1; if (month > 12) // 一年的最后一天,需要同时调整年 月 日 { month = 1; } } else { day += 1; } } else if (month == 2) { // 非闰年28号是2月的最后一天 day = 1; month += 1; } else if (month == 4 || month == 6 || month == 9 || month == 11) { if (day >= 30) // 是30号 { day = 1; month += 1; } else { day += 1; } } return month * 100 + day; // 计算出明天的日期 }
然后观察剩下的一大串if else语句,有很多重复的代码片段,这个现象说明可能比较适合应用合并分支的手法。
所以我们合并分支条件,将所有判定是月末最后一天的条件合并在一起。整个程序的逻辑就简化为是不是月末最后一天,如果是 do somethin 如果不是 do something。
当然,到这里的时候,已经完全可以重新写一套代码,相对来说速度上比改这个代码肯定还要快一些,现实工作中 这种情形也不少遇到。不过这里为了扣住这个blog主题——“修改代码的艺术”,所以下面还是以代码重构的方式进行
要合并分支,首先需要将这些分支集中到同一层。 千万不要直接上下层合并,只要稍微复杂一些,就连怎么死的都不知道。因此先做一次扁平化操作。具体怎么做,之前已经详细讲述了,这里就直接快进
int nextdate(int year, int month, int day) { if (day < 28) {// 如果不是一个月的最后一天,则day直接加1 day += 1; return month * 100 + day; // 计算出明天的日期 } if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && (day >= 31)) { // 这个月的最后一天, 需要同时调整 月 日 day = 1; month += 1; if (month > 12) // 一年的最后一天,需要同时调整年 月 日 { year += 1; month = 1; } } else if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && !(day >= 31)) { day += 1; } else if (month == 2) { // 非闰年28号是2月的最后一天 day = 1; month += 1; } else if ((month == 4 || month == 6 || month == 9 || month == 11) && (day >= 30)) { // 30号是這些月份的最后一天 day = 1; month += 1; } else if ((month == 4 || month == 6 || month == 9 || month == 11) && !(day >= 30)) { day += 1; } return month * 100 + day; // 计算出明天的日期 }
在合并所有判定是月末最后一天的分支 之前,需要先将这些分支移动到相邻的位置。一般而言,if 。。。 else if 。。。 else 是不可以随便上下移动位置的
if (x < 5) { } else if (x < 10) {}
if (x < 10) { } else if (x < 5) {}
if (5 <= x && x < 10) { } else if (x < 5) {}
移动和合并分支
int nextdate(int month, int day) { if (day < 28) {// 如果不是一个月的最后一天,则day直接加1 day += 1; return month * 100 + day; // 计算出明天的日期 } if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && (day >= 31) || (month == 2) || (month == 4 || month == 6 || month == 9 || month == 11) && (day >= 30)) { // 这个月的最后一天, 需要同时调整 月 日 day = 1; month += 1; if (month > 12) // 一年的最后一天,需要同时调整年 月 日 { month = 1; } } else if (((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && !(day >= 31)) || ((month == 4 || month == 6 || month == 9 || month == 11) && day < 30)) { day += 1; } return month * 100 + day; // 计算出明天的日期 }
int nextdate(int month, int day) { if (isLastDayofaYear(day, month)) { // 一年中的最后一天,下一天就是1月1日 day = 1; month = 1; } else if (isLastDayOfaMonth(day, month)) { // 这个月的最后一天,下一天就是下一个月的1号 day = 1; month += 1; } else { // 不是月末最后一天,直接天数+1 day += 1; } return month * 100 + day; // 计算出明天的日期 } private boolean isLastDayOfaMonth( int day, int month) { if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { return day == 31; } else if (month == 4 || month == 6 || month == 9 || month == 11) { return day == 30; } else if (month == 2) { return day == 28; } else { throw new RuntimeException("unknow month"); } } private boolean isLastDayofaYear(int day, int month) { return month==12 && day == 31; }
over
原文地址:http://blog.csdn.net/crylearner/article/details/39090283