一位面试官最近问了我这样一个问题:给定三个布尔变量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 a ? (b ? true : c) : (b ? c : 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'bc + abc' + abc + ab'c

减少使用k - map,可以得到:

bc + ab + ac

可以通过在a'bc和abc' minterms上使用exclusive或,并结合abc和ab'c minterms来进一步减少此值:

b(a ^ c) + ac

当我看到这个问题时,我的第一个想法是:

int count=0;
if (a)
    ++count;
if (b)
    ++count;
if (c)
    ++count;
return count>=2;

在看了其他帖子后,我承认

return (a?1:0)+(b?1:0)+(c?1:0)>=2;

更优雅。我想知道相对运行时是什么。

不过,无论如何,我认为这种解决办法比那种解决办法要好得多

return a&b | b&c | a&c;

variety because is is more easily extensible. What if later we add a fourth variable that must be tested? What if the number of variables is determined at runtime, and we are passed an array of booleans of unknown size? A solution that depends on counting is much easier to extend than a solution that depends on listing every possible combination. Also, when listing all possible combinations, I suspect that it is much easier to make a mistake. Like try writing the code for "any 3 of 4" and make sure you neither miss any nor duplicate any. Now try it with "any 5 of 7".

在我看来,3 / 3都是非常任意的数,函数应该适用于任意的数。为了回答这个问题,我要写一个函数来计算数组中的x是否为真,例如,

bool istrue ( int x, bool[] list)
    y = count true in list
    return y >= x
public static boolean atLeast(int atLeastToBeTrue, boolean...bools){
    int booleansTrue = 0;
    for(boolean tmp : bools){
        booleansTrue += tmp ? 1 : 0;
    }
    return booleansTrue >= atLeastToBeTrue;
}

你可以从varargs a.k.a boolean[]中选择至少有多少你想为真:-)