检查三个布尔值中至少有两个为真

612

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

我的解决方案如下:

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

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


173
将返回语句内联。 - Finglas
82
atLeastTwo(iWantYou, iNeedYou, imEverGonnaLoveYou) - Andrew Grimm
6
Thorbjørn 问道:C语言中是否使用0/非0来表示布尔值?我认为这种情况在C语言中不适用,例如atLeastTwo(0,2,0)。请问您的看法? - Ken
93
为什么人们会给那些最琐碎的问题点赞? - BlueRaja - Danny Pflughoeft
52
通俗易懂的问题会得到很多赞,而过于具体和技术性的问题则不会。 - Jay
显示剩余14条评论
65个回答

2
int count=0;

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if (a)
        count++;
    if (b)
        count++;
    if (c)
        count++;

    if (count>1)
        return true;
    else
        return false;
}

2
我找到了这个解决方案。
boolean atLeastTwo(boolean a, boolean b, boolean c) {
    bool result = !(a ^ b ^ c) && !(!a & !b & !c) || (a & b & c);
    return result;
}

2
这个问题的非简化解决方案是:
a'bc + abc' + abc + ab'c

使用K-Map简化后,得到如下结果:
bc + ab + ac

通过对a'bc和abc'的异或运算,并结合abc和ab'c的最小项,可以进一步减少这个表达式:

b(a ^ c) + ac

2

这绝对是一个关于解决问题和思维方式的问题,而不是你的编码能力。

稍微简洁一点的版本可以是

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

但像先前的某个发帖者所说,如果我在任何我的工作中看到这种代码,我会训斥他的。:)


2
如果目标是返回三个操作数的按位二选三值,算术和迭代方法可能相对无效。在许多CPU架构上,一个好的形式是“return ((a | b) & c) | (a & b);”。这需要四个布尔运算。在单累加器机器上(在小型嵌入式系统中很常见),每个字节总共需要七条指令。形式“return (a & b) | (a & c) | (b & c);”看起来更好,但需要五个布尔运算或在单累加器机器上每个字节需要九条指令。
顺便提一下,在CMOS逻辑中,计算“不是二选三”需要十二个晶体管(相比之下,反相器需要两个,两输入NAND或NOR需要四个,三输入NAND或NOR需要六个)。

2

我没有看到其他人指出的一件事是,在面试中“请给我写些代码”的部分中,通常会说“你能改进吗?”或“你对此完全满意吗?”或“这是尽可能优化了吗?”,当你说你完成时。有可能你听到的“你怎么改进它”是“这可能需要改进;怎么改进?”在这种情况下,将if(x) return true; else return false;习惯用法更改为只是return x是一种改进-但要注意,有时他们只想看看你对问题的反应。我听说有些面试官会坚持认为完美的代码存在缺陷,只是为了看看你如何应对。


2

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

我倾向于使用map-reduce解决方案,它可以接受任何类型的列表和任意的条件。


2

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

您可以使用k-MAP并得出一个布尔表达式...

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

或者if((A && (B || C )) || C) { return true; } else return false;


这不是只有C为真就返回true吗? - user357812
翻译后的文本:糟糕...我忘记添加了一些内容...应该是 if((A && (B || C )) || (B && C)) { return true; } else return false; - Egalitarian

2

如何看待Java中的 (a||b) && (a||c) - 与OP的六次比较相比,只需要三次比较。

错了,我应该早些进行检查。


1
这个有问题。如果a为真,而b和c为假,则会失败。 - CCC

1

如果我将布尔值转换为数字,并且该数字不是2的幂,则它至少有两个true。

a*4 + b*2 + c*1 = N
return( N != 0 && (N&(N-1)) != 0)

我只是提供一个替代方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接