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

我的解决方案如下:

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

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


当前回答

还有一种不太好的方法:

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

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

其他回答

return 1 << $a << $b << $c >= 1 << 2;
return (a==b) ? a : c;

解释:

如果a==b,则两者都为真或都为假。如果两者都为真,我们已经找到了两个真布尔值,并可以返回真(通过返回a)。如果两者都为假,即使c为真,也不可能有两个真布尔值,因此我们返回假(通过返回a)。这是(a==b) ?一个部分。c呢?如果a==b为假,那么a或b中只有一个为真,所以我们找到了第一个真布尔值,剩下的唯一问题是c是否也为真,所以我们返回c作为答案。

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

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

如果你有很多布尔值,操作符重载很容易。

operator fun Boolean.unaryPlus() = if (this) 1 else 0
// ...
if(+bool1 + +bool2 + ... + +boolN > 2) {
    // ...
}

借助于算术运算,这是非常简单的。

boolean a = true;
boolean b = false;
boolean c = true;


// Exactly One boolean value true.
if((a?1:0)+(b?1:0)+(c?1:0)==1) 
   return true;
else
   return false;

// Exactly 2 boolean value true.
if((a?1:0)+(b?1:0)+(c?1:0)==2) 
   return true;
else
   return false;

这就是你如何增加常数的值来检查有多少布尔值为真