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

我的解决方案如下:

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

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


当前回答

这个问题的非约简解是:

a'bc + abc' + abc + ab'c

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

bc + ab + ac

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

b(a ^ c) + ac

其他回答

这样读起来更好:

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

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

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;
    }
}

这类问题可以用卡诺图来解决:

      | C | !C
------|---|----
 A  B | 1 | 1 
 A !B | 1 | 0
!A !B | 0 | 0
!A  B | 1 | 0

由此推断,第一行需要一组,第一列需要两组,得到聚基因润滑剂的最优解:

(C && (A || B)) || (A && B)  <---- first row
       ^
       |
   first column without third case

当然,这个问题更多的是关于你如何解决问题/思考,而不是你实际的编码能力。

一个稍微简洁一点的版本可能是

返回((a ^ b) && (b ^ c)) ^ b

但就像之前的一个帖子说的,如果我在任何我正在编写的代码中看到这个,有人会听到很多。:)

我的第一个想法是

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

但为了便于阅读,我喜欢你们提出的a+b+c>=2的解决方案