下面的布尔表达式怎么写?
我有三个布尔值 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 这是针对生产代码的,因此我更注重代码的可读性而不是性能。
添加 2: 已接受答案,但对于好奇的人来说 - 这是 C#。 :) 这个问题几乎与语言无关。
I've got three boolean values A, B and C. I need to write an IF statement which will execute if and only if no more than one of these values is True. In other words, here is the truth table:
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
What is the best way to write this? I know I can enumerate all possibilities, but that seems... too verbose. :P
Added: Just had one idea:
!(A && B) && !(B && C) && !(A && C)
This checks that no two values are set. The suggestion about sums is OK as well. Even more readable maybe...
(A?1:0) + (B?1:0) + (C?1:0) <= 1
P.S. This is for production code, so I'm going more for code readability than performance.
Added 2: Already accepted answer, but for the curious ones - it's C#. :) The question is pretty much language-agnostic though.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
将它们视为整数 1 和 0,并检查它们的总和是否等于 1 怎么样?
编辑:
现在我们知道它是 c#.net,我认为最具可读性的解决方案看起来有点像
上面隐藏在类库(appcode?)中的内容,我们不必看到它,但可以轻松访问它(例如,在 r# 中按 ctrl+click),然后实现将很简单:
...
how about treating them as integer 1's and 0's, and checking that their sum equals 1?
EDIT:
now that we know that it's c#.net, i think the most readable solution would look somewhat like
the above tucked away in a class library (appcode?) where we don't have to see it, yet can easily access it (ctrl+click in r#, for instance) and then the implementation will simply be:
...
您应该熟悉卡诺地图。 概念最常应用于电子产品,但在这里也非常有用。 这非常简单(虽然维基百科的解释看起来很长——但很彻底)。
You shold familiarize yourself with Karnaugh maps. Concept is most often applied to electronics but is very useful here too. It's very easy (thought Wikipedia explanation does look long -- it's thorough).
(A XOR B XOR C) OR NOT (A OR B OR C)
编辑:正如 Vilx 所指出的,这是不对的。
如果A和B都为1,C为0,则A异或B为0,总结果为0。
怎么样:
非(A 和 B)且非(A 和 C)且非(B 和 C)
(A XOR B XOR C) OR NOT (A OR B OR C)
Edit: As pointed out by Vilx, this isn't right.
If A and B are both 1, and C is 0, A XOR B will be 0, the overall result will be 0.
How about:
NOT (A AND B) AND NOT (A AND C) AND NOT (B AND C)
如果你扭转逻辑,如果你有任何一对布尔值都为真,你希望条件为假:
对于完全不同的东西,你可以将布尔值放入一个数组中并计算有多少个真值:
If you turn the logic around, you want the condition to be false if you have any pair of booleans that are both true:
For something completely different, you can put the booleans in an array and count how many true values there are:
我会追求最大的可维护性和可读性。
I'd go for maximum maintainability and readability.
这里有很多答案,但我还有一个!
There are many answers here, but I have another one!
查找给定真值表的最小布尔表达式的一般方法是使用卡诺图:
http://babbage.cs.qc.edu/courses/Minimize/
网络上有几个在线最小化程序。 这里的(链接到文章,虽然是德语)找到以下表达式:
(!A && !B) || (!A && !C) || (!B && !C)
不过,如果您想要代码可读性,我可能会采用“sum<=1”的想法。 请注意,并非所有语言都保证 false==0 和 true==1 ——但您可能已经意识到这一点,因为您已经在自己的解决方案中处理了它。
A general way of finding a minimal boolean expression for a given truth table is to use a Karnaugh map:
http://babbage.cs.qc.edu/courses/Minimize/
There are several online minimizers on the web. The one here (linked to from the article, it's in German, though) finds the following expression:
(!A && !B) || (!A && !C) || (!B && !C)
If you're going for code readability, though, I would probably go with the idea of "sum<=1". Take care that not all languages guarantee that false==0 and true==1 -- but you're probably aware of this since you've taken care of it in your own solution.
良好的逻辑:
如果需要,请接受提示并进一步简化。
是的,让您自己熟悉卡诺地图
Good ol' logic:
Take the hint and simplify further if you want.
And yeah, get your self familiar with Karnaugh Maps
取决于你想要的是容易理解你想要做什么的东西,还是逻辑上尽可能简单的东西。 其他人发布了逻辑上简单的答案,因此这里是更清楚发生了什么(以及不同输入的结果)的答案:
Depends whether you want something where it's easy to understand what you're trying to do, or something that's as logically simple as can be. Other people are posting logically simple answers, so here's one where it's more clear what's going on (and what the outcome will be for different inputs):
我喜欢加法解决方案,但这里也有一个使用位字段来实现这一点的技巧。
I like the addition solution, but here's a hack to do that with bit fields as well.
d的解决方案代码演示:
Code demonstration of d's solution: