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

我的解决方案如下:

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

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


当前回答

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

bool istrue ( int x, bool[] list)
    y = count true in list
    return y >= x

其他回答

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

bool istrue ( int x, bool[] list)
    y = count true in list
    return y >= x

而不是写:

if (someExpression) {
    return true;
} else {
    return false;
}

写:

return someExpression;

至于表达式本身,是这样的:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return a ? (b || c) : (b && c);
}

或者这个(你觉得哪个更容易理解):

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return a && (b || c) || (b && c);
}

它只测试a和b一次,c最多测试一次。

参考文献

JLS 15.25条件运算符?:

我相信使用普通的布尔运算符(a || b) && (b || c)是很好的,而且更简单。

你可以把这三个字母中的任意一个和另外两个字母中的任意一个交换它仍然是相同的表达式。

在Clojure中:

(defn at-least [n & bools]
  (>= (count (filter true? bools)) n)

用法:

(at-least 2 true false true)
function atLeastTwoTrue($a, $b, $c) {

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