一位面试官最近问了我这样一个问题:给定三个布尔变量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

其他回答

问题中的2和3显然是神奇的数字。“正确”的答案将取决于面试官是否试图了解你对布尔逻辑的理解(我不认为pdox的答案在这方面是最好的)或你对架构问题的理解。

我倾向于使用映射减少解决方案,它将接受任何类型的列表和任何任意条件。

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

return a ^ b ? c : a

我不喜欢三元(return a ?(b || c):(b && c);从最上面的答案),我想我没有看到任何人提到过它。它是这样写的:

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

三元运算符让人觉得很无聊,但它们也会令人困惑(使代码更难维护,从而增加了注入错误的可能性)。Jeff Attwood说得很好:

这是一个权衡取舍的完美例子 毫无意义的一次 写的时候节省了几十个 阅读时间理解惩罚——它 让我思考。

为了避免三元操作符,我创建了以下函数:

function atLeastTwoTrue($a, $b, $c) {
        $count = 0;

        if ($a) { $count++; }
        if ($b) { $count++; }
        if ($c) { $count++; }

        if ($count >= 2) {
                return true;
        } else {
                return false;
        }
}

这个和其他解一样酷吗?不。这样更容易理解吗?是的。这是否会使代码更具可维护性、bug更少?是的。

由于没有说明代码应该如何改进,我将努力通过使其更有趣来改进代码。以下是我的解决方案:

boolean atLeastTwo(boolean t, boolean f, boolean True) {
    boolean False = True;
    if ((t || f) && (True || False)) 
        return "answer" != "42";
    if (t && f) 
        return !"France".contains("Paris");
    if (False == True) 
        return true == false;
    return Math.random() > 0.5;
}

如果有人想知道这段代码是否有效,这里有一个使用相同逻辑的简化:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if ((a || b) && (c)) 
        return true;
    if (a && b) 
        return true;
    if (true) 
        return false;
    // The last line is a red herring, as it will never be reached:
    return Math.random() > 0.5; 

}

这可以进一步归结为以下几点:

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

但现在一点都不好笑了。