我有三个布尔值A,B和C我需要写一个IF语句当且仅当不超过下列值之一为真,将执行。换句话说,这里是真值表:

 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)

此检查,没有两个值被设置。关于资金的建议是OK为好。甚至更可读也许...

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

P.S。这是生产代码,所以我要多为代码的可读性比性能。

新增2:已接受的答案,但对于好奇的 - 这是C#。 :)现在的问题是相当多的语言无关,但。

有帮助吗?

解决方案

怎么样将它们视为整数1和0的,并检查它们的和等于1?

修改

现在,我们知道这是C#.NET,我觉得最可读的解决方案看起来有点像

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

以上在类库局促(?appcode),我们没有看到它,但可以很容易地访问它(CTRL +单击R·,例如),然后实施将仅仅是:

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

...

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

其他提示

您shold熟悉卡诺图。概念最常应用于电子产品,但是是非常有用这里。这很容易(维基百科想解释看起来很长 - 这是彻底的)。

(A XOR B XOR C)OR NOT(A或B或C)

编辑:如Vilx指出的,这是不正确的

如果A和B都为1,C为0,A XOR B将是0,总的结果将是0

如何: NOT(A和B)和NOT(A和C)和NOT(B和C)

如果你把逻辑周围,你想要的条件是假的,如果你有任何一对布尔即都为真的:

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

完全不同的东西,你可以把布尔在一个数组,计算有多少真实值有:

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

我会去维护最大和可读性。

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

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

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

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

好醇”逻辑:

+ = 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))

采取提示,如果你想进一步简化。

和耶,让你自己熟悉卡诺图

要看你是否想要的东西在那里很容易理解你想要做什么,或者说这是因为可以在逻辑上简单。其他人张贴逻辑简单的答案,所以这里的一个地方更清楚发生了什么(什么结果将是不同的输入):

  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"

我喜欢另外的解决方案,但这里有一个黑客这样做与位域为好。

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 */ }

D的溶液的代码示范:

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

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

}
scroll top