一位面试官最近问了我这样一个问题:给定三个布尔变量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) | (c & (a ^ b));

其他回答

他可能不是在寻找像位比较操作符这样复杂的东西(通常不是复杂的,但使用布尔值,使用位操作符是非常奇怪的),或者像转换为int并对它们求和这样非常迂回的东西。

解决这个问题最直接和自然的方法是用这样的表达式:

a ? (b || c): (b && c)

如果你喜欢,可以把它放到一个函数里,但这并不复杂。该解决方案在逻辑上简洁有效。

而不是写:

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条件运算符?:

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

C解。

int two(int a, int b, int c) {
  return !a + !b + !c < 2;
}

或者你可能更喜欢:

int two(int a, int b, int c) {
  return !!a + !!b + !!c >= 2;
}

只是为了使用异或来回答一个相对简单的问题……

return a ^ b ? c : a