[英]XOR of three values
What is the simplest way to do a three-way exclusive OR?做三路异或的最简单方法是什么?
In other words, I have three values, and I want a statement that evaluates to true IFF only one of the three values is true.换句话说,我有三个值,并且我想要一个评估为真 IFF 的语句,只有三个值中的一个为真。
So far, this is what I've come up with:到目前为止,这就是我想出的:
((a ^ b) && (a ^ c) && !(b && c)) || ((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b)) ((c ^ a) && (c ^ b) && !(a && b))
Is there something simpler to do the same thing?有没有更简单的方法来做同样的事情?
Here's the proof that the above accomplishes the task:这是上述完成任务的证明:
a = true; b = true; c = true
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> false
a = true; b = true; c = false
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> false
a = true; b = false; c = true
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> false
a = true; b = false; c = false
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> true
a = false; b = true; c = true
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> false
a = false; b = true; c = false
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> true
a = false; b = false; c = true
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> true
a = false; b = false; c = false
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> false
For exactly three terms, you can use this expression:对于三个术语,您可以使用以下表达式:
(a ^ b ^ c) && !(a && b && c)
The first part is true
iff one or three of the terms are true
.如果其中一个或三个术语为true
true
The second part of the expression ensures that not all three are true
.表达式的第二部分确保并非所有三个都为true
。
Note that the above expression does NOT generalize to more terms.请注意,上述表达式并未推广到更多术语。 A more general solution is to actually count how many terms are true
, so something like this:一个更通用的解决方案是实际计算有多少项是true
,所以像这样:
int trueCount =
(a ? 1 : 0) +
(b ? 1 : 0) +
(c ? 1 : 0) +
... // more terms as necessary
return (trueCount == 1); // or some range check expression etc
bool result = (a?1:0)+(b?1:0)+(c?1:0) == 1;
a^b^c
is only 1 if an uneven number of variables is 1 (two '1' would cancel each other out). a^b^c
只有在奇数个变量为 1 时才为 1(两个 '1' 会相互抵消)。 So you just need to check for the case "all three are 1":所以你只需要检查“所有三个都是1”的情况:
result = (a^b^c) && !(a&&b&&c)
Another possibility:另一种可能:
a ? !b && !c : b ^ c
which happens to be 9 characters shorter than the accepted answer :)这恰好比接受的答案短 9 个字符:)
Better yet on Python:在 Python 上更好:
result = (1 if a else 0)+(1 if b else 0)+(1 if c else 0) == 1
This can be used also on if statements!这也可以用于 if 语句!
It saved my day for CLI mutually exclusive arguments through Click (everyone hates click)它通过 Click 为 CLI 互斥参数节省了我的时间(每个人都讨厌点击)
您也可以尝试(在 C 中):
!!a + !!b + !!c == 1
f= lambda{ |a| [false, false, true].permutation.to_a.uniq.include? a }
p f.call([false, true, false])
p f.call([false, true, true])
$ true $ 真
$ false $假
Because I can.因为我可以。
Here's a general implementation that fails quickly when more than one bool
is found to be true
.这是一个通用实现,当发现多个bool
为true
时会迅速失败。
Usage :用法:
XOR(a, b, c);
Code :代码:
public static bool XOR(params bool[] bools)
{
return bools.Where(b => b).AssertCount(1);
}
public static bool AssertCount<T>(this IEnumerable<T> source, int countToAssert)
{
int count = 0;
foreach (var t in source)
{
if (++count > countToAssert) return false;
}
return count == countToAssert;
}
In C:在 C 中:
#include <stdbool.h>
bool array_xor(size_t array_size, bool[] array) {
int count = 0;
for (int i = 0; i < array_size && count < 2; i++) {
if (array[i]) {
count++;
}
}
return count == 1;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.