逻辑来testing3的4是真的

当且仅当4个布尔值中的3个为True时,我才想返回True

我得到的最接近的是(x ^ y) ^ (a ^ b)

我该怎么办?

我build议你编写代码,以表明你的意思。 如果你想要3个值是真的,那么对于我来说,值3看起来很自然。

例如,在C++

 if ((int)a + (int)b + (int)c + (int)d == 3) ... 

这在C++有很好的定义: standard (§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)) 

当我用来分析一切时,我发现非分支解决scheme比CPU更好地预测代码path,并执行更多的操作。 虽然这里的分支声明中有大约50%的工作。

如果这是Python,我会写

 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): 

很长但很简单,(disjuntive)正常forms:

  (~a & b & c & d) | (a & ~b & c & d) | (a & b & ~c & d) | (a & b & c & ~d) 

这可能是简化的,但需要更多的思考:P

不知道这是简单的,但也许。

((x xor y) and (a and b)) or ((x and y) and (a xor b))

如果你想在编程语言中使用这个逻辑,我的build议是

 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)应该做的伎俩。

请记住,如果对编程问题而言,而不是单纯的逻辑问题,答案显然取决于编程语言的select。 有些语言支持其他人不常见的function。

例如,在C ++中,你可以用下面的方法testing你的条件:

 (a + b + c + d) == 3 

这应该是检查支持从布尔型到整型自动(低级别)转换的语言的最快方法。 但是,这个问题也没有一般的答案。

我能做的最好的是((x ^ y) ^ (a ^ b)) && ((a || x) && (b || y))

 ((a xor b) xor (c xor d)) and ((a or b) and (c or d)) 

第一个expression式search1或3个true的4个。第二个消除0或1(有时2个) true的4个。

Java 8,过滤出错误的值,并计算剩余的真正值:

 public static long count(Boolean... values) { return Arrays.stream(values).filter(t -> t).count(); } 

那么你可以使用它如下:

 if (3 == count(a, b, c, d)) { System.out.println("There... are... THREE... lights!"); } 

很容易概括为检查m项目是否为真。

要检查至lessnBoolean是否为真,(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 } 

另一个 :

((c & d) & (a ^ b)) | ((a & b) & (c ^ d)) ((c & d) & (a ^ b)) | ((a & b) & (c ^ d)) ( 详情 )

这里有一种方法可以用C#和LINQ解决:

 bool threeTrue = new[] { a, b, x, y }.Count(x => x) == 3; 

这就是对称布尔函数S₃(4) 。 对称布尔函数是一个布尔函数,它只取决于input集的数量,而不取决于它们是哪个input。 Knuth在“计算机程序devise艺术”第4卷第7.1.2节中提到了这种types的函数。

S₃(4)可以用7个操作计算如下:

 (x && y && (a || b)) ^ ((x || y) && a && b) 

Knuth表明这是最佳的,这意味着你不能在less于7次的操作中使用正常的操作符: &&, || , ^, <, &&, || , ^, <,>

然而,如果你想用这个语言来使用这个语言,那么使用1代表真, 0代表假,你也可以使用加法:

 x + y + a + b == 3 

这使你的意图很清楚。

 (a && b && (c xor d)) || (c && d && (a xor b)) 

从纯逻辑的angular度来看,这就是我想出来的。

根据鸽子洞原则,如果确切的是3,那么a和b是真的,或c和d是真的。 那么只需要把其中的一个与其中的每一个进行比较就可以了。

Wolfram真相表

如果你使用像卡诺图(Karnaugh Maps)这样的逻辑可视化工具,你会发现这是一个问题,如果你想把它写在一个if(…)行中,你就无法避免一个完整的逻辑术语。 洛皮纳已经显示它,这是不可能写得更简单。 你可以分解一点,但是对于你和机器来说,它会很难读取。

计数的解决scheme并不坏,他们显示你真的以后。 如何有效地进行计数取决于您的编程语言。 使用Python或LinQ的数组解决scheme很好看,但要小心,这是慢的。 沃尔夫的(a + b + x + y)== 3将很好地和快速地工作,但只有当你的语言等同于“真”与1.如果“真”用-1表示,你将不得不testing-3: )

如果你的语言使用真正的布尔值,你可以尝试显式编程(我使用!= XORtesting):

 if (a) { if (b) return (x != y); // a,b=true, so either x or y must be true else return (x && y); // a=true, b=false, so x AND y must be true } else { if (b) return (x && y); // a=false, b=true, so x and y must be true else return false; // a,b false, can't get 3 of 4 } 

“x!= y”只适用于x,y是布尔types的情况。 如果他们是其他types,其中0是假的,其他一切都是真的,那么这可能会失败。 然后使用一个布尔XOR或((bool)x!=(bool)y),或者写“if(x)return(y == false)else return(y == true);”,这是多一点为电脑工作。

如果你的编程语言提供三元?:运算符,你可以缩短它

 if (a) return b ? (x != y) : (x && y); else return b ? (x && y) : false; 

它保持了一点可读性,或者积极地削减

 return a ? (b ? (x != y) : (x && y)) : (b ? (x && y) : false); 

这段代码正好做了三个逻辑testing(a的状态,b的状态,x和y的比较),并且应该比这里的大多数其他答案更快。 但是你需要评论一下,否则3个月后你就不会明白了:)

这里有很多很好的答案。 这是另一个没有人发表的公式:

  a ? (b ? (c ^ d) : (c && d)) : (b && c && d) 

类似于第一个答案,但纯Java:

 int t(boolean b) { return (b) ? 1 : 0; } if (t(x) + t(y) + t(a) + t(b) == 3) return true; return false; 

我更喜欢把它们作为整数来计数,因为它使得代码更具可读性。

Python中 ,要查看元素的迭代中有多less是True,请使用sum (这非常简单):

build立

 import itertools arrays = list(itertools.product(*[[True, False]]*4)) 

实际testing

 for array in arrays: print(array, sum(array)==3) 

产量

 (True, True, True, True) False (True, True, True, False) True (True, True, False, True) True (True, True, False, False) False (True, False, True, True) True (True, False, True, False) False (True, False, False, True) False (True, False, False, False) False (False, True, True, True) True (False, True, True, False) False (False, True, False, True) False (False, True, False, False) False (False, False, True, True) False (False, False, True, False) False (False, False, False, True) False (False, False, False, False) False 

如果您使用的是纸上(非编程)解决scheme,那么K-maps和Quine-McCluskeyalgorithm就是您所追求的,它们可以帮助您缩小布尔函数。

在你的情况下,结果是

 y = (x̄3 ^ x2 ^ x1 ^ x0) ∨ (x3 ^ x̄2 ^ x1 ^ x0) ∨ (x3 ^ x2 ^ x̄1 ^ x0) ∨ (x3 ^ x2 ^ x1 ^ x̄0) 

如果你想以编程的方式,非固定数量的variables和一个自定义的“阈值”,然后简单地遍历一个布尔值列表,并计算“true”的出现是非常简单和直接的。

我想返回true,当且仅当4个布尔值中的3个为真。

给定4个布尔值a,b,x,y,这个任务转换成下面的C语句:

 return (a+b+x+y) == 3; 
 ((a^b)^(x^y))&((a|b)&(x|y)) 

是你想要的。 基本上我把你的代码,并添加检查,如果实际上3是真实的,而不是3是错误的。

没有涉及recursion的答案的编程问题? 不可思议!

有足够的“4个trues中的3个”的答案,但是这里是一个广义的(Java)版本,“正好m个外面”(否则recursion不是真的值得),因为你可以:

 public static boolean containsTrues(boolean[] someBooleans, int anIndex, int truesExpected, int truesFoundSoFar) { if (anIndex >= someBooleans.length) { return truesExpected == truesFoundSoFar; // reached end } int falsesExpected = someBooleans.length - truesExpected; boolean currentBoolean = someBooleans[anIndex]; int truesFound = truesFoundSoFar + (currentBoolean ? 1 : 0); if (truesFound > truesExpected) { return false; } if (anIndex - truesFound > falsesExpected) { return false; // too many falses } return containsTrues(someBooleans, anIndex + 1, truesExpected, truesFound); } 

这可以被称为像这样的东西:

  boolean[] booleans = { true, false, true, true, false, true, true, false }; containsTrues(booleans, 0, 5, 0); 

这应该返回true (因为8个值中的5个是正确的,如预期的那样)。 对“trues”和“falses”这个词不太满意,但是现在不能想到一个更好的名字。注意,当发现了太多的true太多的false值时,recursion停止。

由于可读性是一个大问题,您可以使用描述性函数调用(包装任何build议的实现)。 如果这个计算需要在多个地方完成,函数调用是实现重用的最好方法,并且清楚地说明你在做什么。

 bool exactly_three_true_from(bool cond1, bool cond2, bool cond3, bool cond4) { //... } 

在PHP中,使其更具dynamic性(以防万一您更改条件数等):

 $min = 6; $total = 10; // create our boolean array values $arr = array_map(function($a){return mt_rand(0,1)>0;},range(1,$total)); // the 'check' $arrbools = array_map(function($a){return (int)$a;},$arr); $conditionMet = array_sum($arrbools)>=$min; echo $conditionMet ? "Passed" : "Failed"; 
 (((a AND b) OR (x AND y)) AND ((a XOR b) OR (x XOR y))) 

虽然我可以certificate这是一个很好的解决scheme,但是Sam Hocevar的回答很容易,以后再写和理解。 在我的书中,使它更好。

这里是我写的一些C#代码,因为你激励了我:

它需要任何数量的参数,并会告诉你,如果n是真实的。

  static bool boolTester(int n, params bool[] values) { int sum = 0; for (int i = 0; i < values.Length; i++) { if (values[i] == true) { sum += 1; } } if( sum == n) { return true; } return false; } 

你这样称呼它:

  bool a = true; bool b = true; bool c = true; bool d = false; bool test = false; test = boolTester(3, a, b, c, d); 

所以你现在可以testing7/9或15/100。