这里作为(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