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

我的解决方案如下:

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

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


当前回答

另一种方法是使用Java 8的Stream功能,用于任意数量的布尔值。如果Stream在处理所有元素之前达到极限,则会短路:

public static boolean atLeastTrue(int amount, Boolean ... booleans) {
    return Stream.of(booleans).filter(b -> b).limit(amount).count() == amount;
}

public static void main(String[] args){
    System.out.println("1,2: " + atLeastTrue(1, true, false, true));
    System.out.println("1,1: " + atLeastTrue(1, false, true));
    System.out.println("1,0: " + atLeastTrue(1, false));
    System.out.println("1,1: " + atLeastTrue(1, true, false));
    System.out.println("2,3: " + atLeastTrue(2, true, false, true, true));
    System.out.println("3,2: " + atLeastTrue(3, true, false, true, false));
    System.out.println("3,3: " + atLeastTrue(3, true, true, true, false));
}

输出:

1,2: true
1,1: true
1,0: false
1,1: true
2,3: true
3,2: false
3,3: true

其他回答

它应该是:

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

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

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

另一个:

return a? b||c : b&&c
int count=0;

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if (a)
        count++;
    if (b)
        count++;
    if (c)
        count++;

    if (count>1)
        return true;
    else
        return false;
}

这样读起来更好:

if (a) {
    return b || c;
} 
else {
    return b && c;
}

另一个直接代码的例子:

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

显然,这不是最简洁的代码。

齿顶高

另一个(稍微优化的)版本:

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

这可能会运行得稍微快一点,假设与0的比较将比与2的比较使用更快(或更少)的代码。