一位面试官最近问了我这样一个问题:给定三个布尔变量a、b和c,如果三个变量中至少有两个为真,则返回true。
我的解决方案如下:
boolean atLeastTwo(boolean a, boolean b, boolean c) {
if ((a && b) || (b && c) || (a && c)) {
return true;
}
else{
return 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.
哪一种是“改进”的,很大程度上取决于具体情况。
三元运算符让人觉得很无聊,但它们也会令人困惑(使代码更难维护,从而增加了注入错误的可能性)。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更少?是的。
最明显的改进是:
// There is no point in an else if you already returned.
boolean atLeastTwo(boolean a, boolean b, boolean c) {
if ((a && b) || (b && c) || (a && c)) {
return true;
}
return false;
}
然后
// There is no point in an if(true) return true otherwise return false.
boolean atLeastTwo(boolean a, boolean b, boolean c) {
return ((a && b) || (b && c) || (a && c));
}
但这些改进都是微不足道的。