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

我的解决方案如下:

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

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


当前回答

供你参考,这只是一个完整加法器的执行部分。在硬件中,您可以根据不同的布尔表达式使用逻辑工作来确定最佳电路。我猜传统的异或解决方案要比海报上展示的不那么简洁的表达式花费更多的精力。

其他回答

而不是写:

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

return (a==b) ? a : c;

解释:

如果a==b,则两者都为真或都为假。如果两者都为真,我们已经找到了两个真布尔值,并可以返回真(通过返回a)。如果两者都为假,即使c为真,也不可能有两个真布尔值,因此我们返回假(通过返回a)。这是(a==b) ?一个部分。c呢?如果a==b为假,那么a或b中只有一个为真,所以我们找到了第一个真布尔值,剩下的唯一问题是c是否也为真,所以我们返回c作为答案。

下面是使用map/reduce的另一个实现。在分布式环境中,这可以很好地扩展到数十亿布尔值©。使用MongoDB:

创建数据库的布尔值:

db.values.insert({value: true});
db.values.insert({value: false});
db.values.insert({value: true});

创建map, reduce函数:

编辑:我喜欢CurtainDog的回答有映射/减少适用于泛型列表,所以这里有一个地图函数,它接受一个回调,决定一个值是否应该被计数。

var mapper = function(shouldInclude) {
    return function() {
        emit(null, shouldInclude(this) ? 1 : 0);
    };
}

var reducer = function(key, values) {
    var sum = 0;
    for(var i = 0; i < values.length; i++) {
        sum += values[i];
    }
    return sum;
}

运行map / reduce:

var result = db.values.mapReduce(mapper(isTrue), reducer).result;

containsMinimum(2, result); // true
containsMinimum(1, result); // false


function isTrue(object) {
    return object.value == true;
}

function containsMinimum(count, resultDoc) {
    var record = db[resultDoc].find().next();
    return record.value >= count;
}

供你参考,这只是一个完整加法器的执行部分。在硬件中,您可以根据不同的布尔表达式使用逻辑工作来确定最佳电路。我猜传统的异或解决方案要比海报上展示的不那么简洁的表达式花费更多的精力。

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

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;

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