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

我的解决方案如下:

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

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


当前回答

最明显的改进是:

// There is no point in an else if you already returned.
boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if ((a && b) || (b && c) || (a && c)) {
        return true;
    }
    return false;
}

然后

// There is no point in an if(true) return true otherwise return false.
boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return ((a && b) || (b && c) || (a && c));
}

但这些改进都是微不足道的。

其他回答

return (a==b) ? a : c;

解释:

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

它应该是:

(a || b && c) && (b || c && a)

此外,如果true自动转换为1,false自动转换为0:

(a + b*c) * (b + c*a) > 0

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

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;

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

不是在性能的上下文中,而是在良好的代码(可扩展和可读的代码,可以重用)

     static boolean trueBooleans (int howMany,boolean ... bools)
     {
      int total = 0;

      for (boolean b:bools)
        if (b && (++total == howMany)) return true;


      return false;
    }

在我看来,在编写Java时,易于处理意外更改和无重复代码比简洁(脚本语言领域)或快速程序更重要。

这个怎么样:

(a - b) ? c : a