尝试减少/优化if / else块以使其更具可读性

时间:2014-03-11 21:57:30

标签: java if-statement

我有以下代码块。基本上它决定了棒球运动员是否获得了多个基础,如果有人在第1 /第2 /第3位,会发生什么。我这样做了蛮力但有没有办法重写这个以大幅减少行数?我无法想出一个好办法。

    int runsScored = 0;
    switch (action) {
        case 0:
            break;
        case 1:
            if (third) {
                if (second) {
                    if (first) {
                        runsScored = 2;
                        second = false;
                    } else {
                        runsScored = 2;
                        first = true;
                        second = false;
                        third = false;
                    }
                } else {
                    if (first) {
                        runsScored = 1;
                        second = true;
                        third = false;
                    } else {
                        runsScored = 1;
                        first = true;
                        third = false;
                    }
                }
            } else {
                if (second) {
                    if (first) {
                        third = true;
                    } else {
                        first = true;
                    }
                } else {
                    if (first) {
                        second = true;
                    } else {
                        first = true;
                    }
                }
            }
            break;
        case 2:
            if (third) {
                if (second) {
                    if (first) {
                        runsScored = 2;
                        first = false;
                    } else {
                        runsScored = 2;
                        third = false;
                    }
                } else {
                    if (first) {
                        runsScored = 1;
                        second = true;
                    } else {
                        runsScored = 1;
                        second = true;
                        third = false;
                    }
                }
            } else {
                if (second) {
                    if (first) {
                        runsScored = 1;
                        third = true;
                        second = true;
                        first = false;
                    } else {
                        runsScored = 1;
                    }
                } else {
                    if (first) {
                        first = false;
                        second = true;
                        third = true;
                    } else {
                        second = true;
                    }
                }
            }
            break;
        case 3:
            if (third) {
                if (second) {
                    if (first) {
                        runsScored = 3;
                        first = false;
                        second = false;
                        third = true;
                    } else {
                        runsScored = 2;
                        second = false;
                    }
                } else {
                    if (first) {
                        runsScored = 2;
                        first = false;
                    } else {
                        runsScored = 1;
                    }
                }
            } else {
                if (second) {
                    if (first) {
                        runsScored = 2;
                        third = true;
                        second = false;
                        first = false;
                    } else {
                        runsScored = 1;
                        second = false;
                        third = true;
                    }
                } else {
                    if (first) {
                        runsScored = 1;
                        first = false;
                        second = false;
                        third = true;
                    } else {
                        third = true;
                    }
                }
            }
            break;
        case 4:
            if (third) {
                if (second) {
                    if (first) {
                        runsScored = 4;
                        first = false;
                        second = false;
                        third = false;
                    } else {
                        runsScored = 3;
                        second = false;
                        third = false;
                    }
                } else {
                    if (first) {
                        runsScored = 3;
                        first = false;
                        third = false;
                    } else {
                        runsScored = 2;
                        third = false;
                    }
                }
            } else {
                if (second) {
                    if (first) {
                        runsScored = 3;
                        third = false;
                        second = false;
                        first = false;
                    } else {
                        runsScored = 2;
                        second = false;
                        third = false;
                    }
                } else {
                    if (first) {
                        runsScored = 2;
                        first = false;
                        second = false;
                        third = false;
                    } else {
                        runsScored = 1;
                    }
                }
            }
            break;
        default:
            throw new AssertionError();
    }
    return runsScored;

4 个答案:

答案 0 :(得分:1)

好吧,我会用课程来描述这个并让它自我管理,但这是一个很好的第一步。

        if (third) {
            if (second) {
                if (first) {
                    runsScored = 2;
                    second = false;
                } else {
                    runsScored = 2;
                    first = true;
                    second = false;
                    third = false;
                }

        if (third) {
            if (second) {
                    runsScored = 2;
                    second = false;
                if (!first) {
                    first = true;
                    third = false;
                }

即。在else的两边分解相同的代码。一旦你清除了一些灌木丛,就会看到更简单的东西。

答案 1 :(得分:1)

我使用按位运算符(shift和bitwise和)

(见http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

   int runsScored = 0;
   int action=1;
   boolean first = false;
   boolean second = true;
   boolean third = true;

   // Encode the bases in a bitstring.
   int onbases = 0;
   onbases += third ? 1 : 0;
   onbases <<= 1;
   onbases += second ? 1 : 0;
   onbases <<= 1;
   onbases += first ? 1 : 0;
   onbases <<= 1;

   // Bitmasks for use in the loop.
   int homeplate = 16;
   int basesloaded = 2+4+8;

   onbases += 1; // Represent the batter who hasn't yet left the plate.
   for (int i=0; i<action; i++) {
       onbases <<= 1;
       if ((onbases & homeplate) > 0) {
           runsScored += 1;
       }
   }
   // Remove the "players" who crossed home plate.
   onbases &= basesloaded;

   // onbases now reflects who's on base *after* the run.
   // Decode the bitstring.
   first = (onbases & 2) > 0;
   second = (onbases & 4) > 0;
   third = (onbases & 8) > 0;

Integer.toBinaryString(int)对于调试非常有用,如果你使用这些运算符,我发现在括号上加重是有帮助的,因为操作顺序有时并不直观。

编辑:我之前发布的内容忘了将击球手放在底座上。我相信它是固定的。

答案 2 :(得分:0)

假设你的action变量是击球手最终的基础,first, second, third是基础击球员的布尔值:

可以将它们转换为单个数组,而不是检查每个布尔值。例如,第一个和第三个的跑步者看起来像[1,0,1]。第二名和第三名的跑步者看起来像[0,1,1]。然后你可以编写一个函数,它接收你的action变量和基数组,并返回运行次数和新的基数数组。

这当然可以从case语句中删除嵌套语句,但也许您可以想出一种方法来使这项工作比嵌套if更好?

答案 3 :(得分:0)

布尔人的简短版本(仅限):

boolean new_first = (action == 1) || (action == 2) && (first &!second & third);
boolean new_second = (action == 2) || (action == 1
                        && (first && !(second && third))
                        || (!first && second && !third));
boolean new_third = (action == 3)
        || (action == 2 && first)
        || (action == 1 && (first && second));

runsScored部分更难。