进行三向异或的最简单方法是什么?
换句话说,我有三个值,并且我想要一个评估为真IFF的语句,只有三个值的一个为真。
到目前为止,这是我提出的:
((a ^ b)&&(a ^ c)&&!(b&& c))|| ((b ^ a)&&(b ^ c)&&!(a&& c))|| ((c ^ a)&&(c ^ b)&&!(a&& b))
是否有更简单的事情做同样的事情?
以上是上述完成任务的证明:
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
答案 0 :(得分:41)
对于三个术语,您可以使用以下表达式:
(a ^ b ^ c) && !(a && b && c)
如果一个或三个术语为true
,则第一部分为true
。表达式的第二部分确保并非所有三个都是true
。
请注意,上面的表达式 NOT 概括为更多术语。更通用的解决方案是实际计算有多少项是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
答案 1 :(得分:11)
bool result = (a?1:0)+(b?1:0)+(c?1:0) == 1;
答案 2 :(得分:9)
a^b^c
仅为1。所以你只需要检查“三个都是1”的情况:
result = (a^b^c) && !(a&&b&&c)
答案 3 :(得分:5)
另一种可能性:
a ? !b && !c : b ^ c
恰好比接受的答案短9个字符:)
答案 4 :(得分:2)
您也可以尝试(在C中):
!!a + !!b + !!c == 1
答案 5 :(得分:1)
如果发现多个bool
为true
,则此常规实施会很快失败。
<强>用法强>:
XOR(a, b, c);
<强>代码强>:
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;
}
答案 6 :(得分: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
因为我可以。
答案 7 :(得分:0)
在Python上更好:
result = (1 if a else 0)+(1 if b else 0)+(1 if c else 0) == 1
这也可以用于if语句!
通过Click(每个人都不喜欢click),它为CLI互斥参数节省了我的一天