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

我的解决方案如下:

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

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


当前回答

X = OR(a+b,c)

a b c X

1, 1, 0, 1

0, 0, 1, 1

0, 1, 1, 1

其他回答

在Clojure中:

(defn at-least [n & bools]
  (>= (count (filter true? bools)) n)

用法:

(at-least 2 true false true)

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

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

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

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

在Ruby中:

[a, b, c]。计数{|x| x} >= 2

这可以在JavaVM上的JRuby中运行。: -)

If the goal is to return a bitwise two-out-of-three value for three operands, arithmetic and iterative approaches are apt to be relatively ineffective. On many CPU architectures, a good form would be "return ((a | b) & c) | (a & b);". That takes four boolean operations. On single-accumulator machines (common in small embedded systems) that's apt to take a total of seven instructions per byte. The form "return (a & b) | (a & c) | (b & c);" is perhaps nicer looking, but it would require five boolean operations, or nine instructions per byte on a single-accumulator machine.

顺便提一下,在CMOS逻辑中,计算“不是三选二”需要12个晶体管(相比之下,逆变器需要2个晶体管,双输入NAND或NOR需要4个晶体管,而三输入NAND或NOR需要6个晶体管)。

通过真值表计算:

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