我有三个布尔值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#。 :)这个问题几乎与语言无关。
答案 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
}