如何编写以下布尔表达式?

时间:2009-07-08 11:33:20

标签: boolean-expression

我有三个布尔值A,B和C.我需要编写一个IF语句,当且仅当这些值中的一个不是True时才会执行。换句话说,这是真值表:

 A | B | C | Result
---+---+---+--------
 0 | 0 | 0 |   1
 0 | 0 | 1 |   1
 0 | 1 | 0 |   1
 0 | 1 | 1 |   0
 1 | 0 | 0 |   1
 1 | 0 | 1 |   0
 1 | 1 | 0 |   0
 1 | 1 | 1 |   0

写这个的最好方法是什么?我知道我可以列举所有可能性,但这似乎......太冗长了。 :P

已添加:只有一个想法:

!(A&& B)&& !(B& C)&& !(A&& C)

检查没有设置两个值。关于总和的建议也是可以的。更可读也许......

(A?1:0)+(B?1:0)+(C?1:0)< = 1

P.S。这是针对生产代码的,所以我的代码可读性要高于性能。

已添加2:已经接受的答案,但对于好奇的答案 - 它是C#。 :)这个问题几乎与语言无关。

11 个答案:

答案 0 :(得分:11)

如何将它们视为整数1和0,并检查它们的总和是否等于1?

编辑

现在我们知道它是c#.net,我认为最易读的解决方案看起来有点像

public static class Extensions
{
    public static int ToInt(this bool b)
    {
        return b ? 1 : 0;
    }
}

以上隐藏在一个类库(appcode?)中,我们不必看到它,但可以轻松访问它(例如ctrl +在r#中单击),然后实现将只是:< / p>

public bool noMoreThanOne(params bool[] bools) 
{ 
    return bools.ToList().Sum(b => b.ToInt()) <= 1; 
}

...

bool check = noMoreThanOne(true, true, false, any, amount, of, bools);

答案 1 :(得分:9)

你应该熟悉Karnaugh maps。概念通常应用于电子产品,但在这里也非常有用。这很容易(认为维基百科的解释确实很长 - 很彻底)。

答案 2 :(得分:6)

(XOR B XOR C)或不(A或B或C)

编辑:正如Vilx所指出的那样,这是不对的。

如果A和B均为1,且C为0,则A XOR B为0,整体结果为0.

怎么样: NOT(A和B)AND NOT(A和C)AND NOT(B和C)

答案 3 :(得分:3)

如果你改变逻辑,如果你有任何一对布尔都是真的,你希望条件为假:

if (! ((a && b) || (a && c) || (b && c))) { ... }

对于完全不同的东西,你可以将布尔值放在一个数组中,并计算有多少真值:

if ((new bool[] { a, b, c }).Where(x => x).Count() <= 1) { ... }

答案 4 :(得分:3)

我会追求最大的可维护性和可读性。

static bool ZeroOrOneAreTrue(params bool[] bools)
{
    return NumThatAreTrue(bools) <= 1;
}

static int NumThatAreTrue(params bool[] bools)
{
    return bools.Where(b => b).Count();
}

答案 5 :(得分:2)

这里有很多答案,但我有另一个答案!

a ^ b ^ c ^ (a == b && b == c)

答案 6 :(得分:1)

查找给定真值表的最小布尔表达式的一般方法是使用卡诺图:

http://babbage.cs.qc.edu/courses/Minimize/

网上有几个在线最小化器。这里的一个(链接到文章,但它是德语),找到以下表达式:

(!A&amp;&amp;!B)|| (!A&amp;&amp;!C)|| (!B&amp;&amp;!C)

但是,如果你想要代码可读性,我可能会想到“sum&lt; = 1”。注意并非所有语言都保证false == 0和true == 1 - 但是您可能已经意识到这一点,因为您已经在自己的解决方案中处理了它。

答案 7 :(得分:0)

好的逻辑:

+ = OR
. = AND

R = Abar.Bbar.Cbar + Abar.Bbar.C + Abar.B.Cbar + A.Bbar.Cbar
  = Abar.Bbar.(Cbar + C) + Abar.B.Cbar + A.Bbar.Cbar
  = Abar.Bbar + Abar.B.Cbar + A.Bbar.Cbar
  = Abar.Bbar + CBar(A XOR B)
  = NOT(A OR B) OR (NOT C AND (A XOR B))

如果需要,请进行提示并进一步简化。

是的,让自己熟悉卡诺图

答案 8 :(得分:0)

取决于你是否想要一些容易理解你正在尝试做什么的东西,或者那些在逻辑上很简单的东西。其他人发布逻辑上简单的答案,所以这里有一个更明确的是什么(以及不同输入的结果):

  def only1st(a, b, c):
    return a and not b and not c

  if only1st(a, b, c) or only1st(b, a, c) or only1st(c, a, b):
    print "Yes"
  else:
    print "No"

答案 9 :(得分:0)

我喜欢添加解决方案,但这也是一个黑客,也可以使用位字段。

inline bool OnlyOneBitSet(int x)
{
    // removes the leftmost bit, if zero, there was only one set.
    return x & (x-1) == 0;
}

// macro for int conversion
#define BOOLASINT(x) ((x)?1:0)

// turn bools a, b, c into the bit field cba
int i = (BOOLASINT(a) << 0) | BOOLASINT(b) << 1 | BOOLASINT(c) << 2;

if (OnlyOneBitSet(i)) { /* tada */ }

答案 10 :(得分:0)

解决方案的代码演示:

int total=0;
if (A) total++;
if (B) total++;
if (C) total++;

if (total<=1) // iff no more than one is true.
{
    // execute

}