一位面试官最近问了我这样一个问题:给定三个布尔变量a、b和c,如果三个变量中至少有两个为真,则返回true。

我的解决方案如下:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if ((a && b) || (b && c) || (a && c)) {
        return true;
    }
    else{
        return false;
    }
}

他说这还可以进一步改进,但如何改进呢?


当前回答

函数ko返回答案:

static int ho(bool a)
{
    return a ? 1 : 0;
}

static bool ko(bool a, bool b, bool c)
{
    return ho(a) + ho(b) + ho(c) >= 2 ? true : false;
}

其他回答

还有一种不太好的方法:

return (Boolean.valueOf(a).hashCode() + Boolean.valueOf(b).hashCode() + Boolean.valueOf(c).hashCode()) < 3705);

布尔哈希码值固定为true为1231,false为1237,因此同样可以使用<= 3699

这类问题可以用卡诺图来解决:

      | C | !C
------|---|----
 A  B | 1 | 1 
 A !B | 1 | 0
!A !B | 0 | 0
!A  B | 1 | 0

由此推断,第一行需要一组,第一列需要两组,得到聚基因润滑剂的最优解:

(C && (A || B)) || (A && B)  <---- first row
       ^
       |
   first column without third case

函数ko返回答案:

static int ho(bool a)
{
    return a ? 1 : 0;
}

static bool ko(bool a, bool b, bool c)
{
    return ho(a) + ho(b) + ho(c) >= 2 ? true : false;
}

问题中的2和3显然是神奇的数字。“正确”的答案将取决于面试官是否试图了解你对布尔逻辑的理解(我不认为pdox的答案在这方面是最好的)或你对架构问题的理解。

我倾向于使用映射减少解决方案,它将接受任何类型的列表和任何任意条件。

目前的Java 8,我真的更喜欢这样的东西:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return Stream.of(a, b, c).filter(active -> active).count() >= 2;
}