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

我的解决方案如下:

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

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


当前回答

下面是一个测试驱动的通用方法。虽然不像目前提供的大多数解决方案那样“高效”,但是清晰、经过测试、有效且通用。

public class CountBooleansTest extends TestCase {
    public void testThreeFalse() throws Exception {
        assertFalse(atLeastTwoOutOfThree(false, false, false));
    }

    public void testThreeTrue() throws Exception {
        assertTrue(atLeastTwoOutOfThree(true, true, true));
    }

    public void testOnes() throws Exception {
        assertFalse(atLeastTwoOutOfThree(true, false, false));
        assertFalse(atLeastTwoOutOfThree(false, true, false));
        assertFalse(atLeastTwoOutOfThree(false, false, true));
    }

    public void testTwos() throws Exception {
        assertTrue(atLeastTwoOutOfThree(false, true, true));
        assertTrue(atLeastTwoOutOfThree(true, false, true));
        assertTrue(atLeastTwoOutOfThree(true, true, false));
    }

    private static boolean atLeastTwoOutOfThree(boolean b, boolean c, boolean d) {
        return countBooleans(b, c, d) >= 2;
    }

    private static int countBooleans(boolean... bs) {
        int count = 0;
        for (boolean b : bs)
            if (b)
                count++;
        return count;
    }
}

其他回答

设三个布尔值为A,B和C....

你可以使用一个k-MAP和一个布尔表达式…

在这种情况下,布尔表达式将是A(B+C) +C

或者if(A && (B || C) || C) { 返回true; } 其他的 返回错误;

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

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

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


      return false;
    }

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

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

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;

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

函数ko返回答案:

static int ho(bool a)
{
    return a ? 1 : 0;
}

static bool ko(bool a, bool b, bool c)
{
    return ho(a) + ho(b) + ho(c) >= 2 ? true : false;
}

这真的取决于你对“改进”的定义:

清晰吗?

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

反之亦然?

boolean moreThanTwo(boolean a, boolean b, boolean c)
{
    return a == b ? a : c;
}

更一般的?

boolean moreThanXTrue(int x, boolean[] bs)
{
    int count = 0;

    for(boolean b : bs)
    {
        count += b ? 1 : 0;

        if(count > x) return true;
    }

    return false;
}

更多的可伸缩的吗?

boolean moreThanXTrue(int x, boolean[] bs)
{
    int count = 0;

    for(int i < 0; i < bs.length; i++)
    {
        count += bs[i] ? 1 : 0;

        if(count > x) return true;

        int needed = x - count;
        int remaining = bs.length - i;

        if(needed >= remaining) return false;
    }

    return false;
}

更快呢?

// Only profiling can answer this.

哪一种是“改进”的,很大程度上取决于具体情况。