我建议以表达你想要的方式编写代码。如果你希望有3个值为真,那么在某处出现值3似乎是很自然的。
例如,在C++
中:
if ((int)a + (int)b + (int)c + (int)d == 3)
...
这在C++
中有明确定义: 标准(§4.7/4)
指出,将bool
转换为int
将得到期望的值0或1。
在Java和C#中,您可以使用以下结构:
if ((a?1:0) + (b?1:0) + (c?1:0) + (d?1:0) == 3)
...
#1: 使用条件运算符 ?::3或4个操作
A ^ B ? C & D : ( C ^ D ) & A
#2 非分支,7个操作
(A ^ B ^ C ^ D) & ((A & B) | (C & D))
在我还对所有东西进行剖析的时候,我发现非分支解决方案在每个操作上比较快,因为CPU可以更好地预测代码路径,并同时执行更多的操作。然而,在这里的分支语句中要少大约50%的工作量。
if [a, b, c, d].count(True) == 3:
或者
if [a, b, c, d].count(False) == 1:
或者
if [a, b, c, d].count(False) == True:
# In Python True == 1 and False == 0
或者
print [a, b, c, d].count(0) == 1
或者
print [a, b, c, d].count(1) == 3
或者
if a + b + c + d == 3:
或者
if sum([a, b, c, d]) == 3:
所有这些工作都是因为在Python中,布尔值是整数的子类。
if len(filter(bool, [a, b, c, d])) == 3:
或者,受到这个 巧妙的技巧 的启发,
data = iter([a, b, c, d])
if not all(data) and all(data):
a=5;not not a == 1
。没有真正的布尔类型的缺点。 - Vooif ([x,y,z,w].filter(x => x).length == 3)
(注意:它需要ES6中的箭头函数语法)。 - ComFreek长而非常简单的(离散)正规式:
(~a & b & c & d) | (a & ~b & c & d) | (a & b & ~c & d) | (a & b & c & ~d)
可能可以简化,但那需要更多的思考:P
(a & b & (c ^ d)) | ((a ^ b) & c & d)
怎么样? - user253751可能不太简单,但或许更易懂。
如果您想在编程语言中使用此逻辑,我的建议是
bool test(bool a, bool b, bool c, bool d){
int n1 = a ? 1 : 0;
int n2 = b ? 1 : 0;
int n3 = c ? 1 : 0;
int n4 = d ? 1 : 0;
return n1 + n2 + n3 + n4 == 3;
}
或者,如果您愿意,您可以将所有这些内容放在一行中:
return (a ? 1 : 0) + (b ? 1 : 0) + (C ? 1 : 0) + (d ? 1 : 0) == 3;
n of m
:bool test(bool *values, int n, int m){
int sum = 0;
for(int i = 0; i < m; i += 1){
sum += values[i] ? 1 : 0;
}
return sum == n;
}
这个答案取决于表示系统,但如果只有0被解释为false,且not(false)
始终返回相同的数值,那么not(a) + not(b) + not(c) + not(d) = not(0)
就能解决问题。
请注意,SO是用于编程问题而非纯逻辑问题,因此答案显然取决于选择的编程语言。一些语言支持其他语言不常见的功能。
例如,在C++中,您可以使用以下方式测试条件:
(a + b + c + d) == 3
如果语言支持从布尔类型自动转换为整数类型,这应该是执行检查的最快方式。但是,对于这个问题并没有通用答案。
检查至少有n
个Boolean
为真(n必须小于或等于所有Boolean
的总数:p)
if (((a ? 1:0) + (b ? 1:0 ) + (c ? 1:0) + (d ? 1:0 )) >= n) {
// do the rest
}
编辑:在@Cruncher的评论后
检查4个中的3个boolean
if (((a ? 1:0) + (b ? 1:0 ) + (c ? 1:0) + (d ? 1:0 )) == 3) {
// do the rest
}
另一个:
not a ^ not b ^ not c ^ not d
才为真。这意味着,在原来的值中,恰好有一个是假的。 - Ingo(!a&&b&&c&&d) || (a&&!b&&c&&d) || (a&&b&&!c&&d) || (a&&b&&c&&!d)
。 - Jason C