逻辑测试4中的3个是真的

Sim*_*ang 163 boolean-logic

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

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

我该怎么办?

sam*_*var 247

我建议以表明你的意思的方式编写代码.如果你想要3个值是真的,我觉得值3出现在某个地方似乎很自然.

例如,在C++:

if ((int)a + (int)b + (int)c + (int)d == 3)
    ...
Run Code Online (Sandbox Code Playgroud)

这在C++以下内容中有明确定义:standard (§4.7/4)指示转换boolint给出预期值0或1.

在Java和C#中,您可以使用以下构造:

if ((a?1:0) + (b?1:0) + (c?1:0) + (d?1:0) == 3)
    ...
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的答案.这看起来像是X/Y的情况."他想用Y做X,但不知道怎么做Y.他没有问X,他问Y." 除非他正在设计一个逻辑电路或类似的东西(然后他会在错误的站点),所以最好的方法是以**可读**的方式. (23认同)
  • +1 ......而后者也用C/C++编译 (10认同)
  • `if(!! a + !! b + !! c + !! d == 3)`更容易编写,虽然我不知道编译器是否优化了 (3认同)
  • @NothingsImpossible这个问题没有XY.关于解决编程中一个相当常见的问题,这是一个清晰而直截了当的问题.Y无关紧要. (2认同)
  • 请注意,在 c++ 中,不需要从 bool 到 int 的转换。 (2认同)

Nam*_*ace 89

#1:使用分支?:3或4个操作

A ^ B ? C & D : ( C ^ D ) & A
Run Code Online (Sandbox Code Playgroud)

#2非分支,7个操作

(A ^ B ^ C ^ D) & ((A & B) | (C & D))
Run Code Online (Sandbox Code Playgroud)

回到我用来描述所有内容时,我发现非分支解决方案操作操作起来要快得多,因为CPU可以更好地预测代码路径,并且可以串联执行更多操作.尽管如此,分支声明中的工作量减少了约50%.

  • +1 - 而对于大多数编程语言,其他答案更好,而#2是纯布尔逻辑中的最佳答案. (17认同)
  • [Wolframalpha真值表](https://www.wolframalpha.com/input/?i=%28A+xor+B+xor+C+xor+D%29+and+%28%28A+and+B%29+对于#2,+ + 28C +和+ D%29%29 +真值+表) (2认同)

the*_*eye 68

如果这是Python,我会写的

if [a, b, c, d].count(True) == 3:
Run Code Online (Sandbox Code Playgroud)

要么

if [a, b, c, d].count(False) == 1:
Run Code Online (Sandbox Code Playgroud)

要么

if [a, b, c, d].count(False) == True:
# In Python True == 1 and False == 0
Run Code Online (Sandbox Code Playgroud)

要么

print [a, b, c, d].count(0) == 1
Run Code Online (Sandbox Code Playgroud)

要么

print [a, b, c, d].count(1) == 3
Run Code Online (Sandbox Code Playgroud)

要么

if a + b + c + d == 3:
Run Code Online (Sandbox Code Playgroud)

要么

if sum([a, b, c, d]) == 3:
Run Code Online (Sandbox Code Playgroud)

所有这些都有用,因为布尔值是Python中整数的子类.

if len(filter(bool, [a, b, c, d])) == 3:
Run Code Online (Sandbox Code Playgroud)

或者,受到这个巧妙的伎俩的启发,

data = iter([a, b, c, d])
if not all(data) and all(data):
Run Code Online (Sandbox Code Playgroud)

  • +1这可以通过正确地将其转换为Python来解决问题. (17认同)

Gas*_*lea 52

长而简单,(分离)正常形式:

 (~a & b & c & d) | (a & ~b & c & d) | (a & b & ~c & d) | (a & b & c & ~d)
Run Code Online (Sandbox Code Playgroud)

它可能会简化,但需要更多思考:P

  • 怎么样`(a&b&(c ^ d))| ((a ^ b)&c&d)`? (8认同)
  • @Ben只是为你提供了各种正常形式,它已经在(DNF). (2认同)
  • 是的,@ immibis,根据Wolfram Alpha的说法,它的DNF是我写的公式,所以它是相同的布尔函数. (2认同)
  • +1因为我认为阅读代码的人会比其他答案更快地理解正在尝试的内容. (2认同)

fro*_*tto 22

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

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;
}
Run Code Online (Sandbox Code Playgroud)

或者如果您愿意,您可以将所有这些放在一行中:

return (a ? 1 : 0) + (b ? 1 : 0) + (C ? 1 : 0) + (d ? 1 : 0) == 3;
Run Code Online (Sandbox Code Playgroud)

您也可以将此问题归纳为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;
}
Run Code Online (Sandbox Code Playgroud)

  • 打败我.可读性每次都胜过聪明.+1 (12认同)

Mat*_*rke 20

这个答案取决于表示系统,但如果0是唯一被解释为false的值,并且not(false)总是返回相同的数值,那么not(a) + not(b) + not(c) + not(d) = not(0)应该这样做.


GOT*_*O 0 17

请记住,如果编程问题而不仅仅是逻辑问题,答案显然取决于编程语言的选择.某些语言支持其他语言不常见的功能.

例如,在C++中,您可以使用以下方法测试您的条件:

(a + b + c + d) == 3
Run Code Online (Sandbox Code Playgroud)

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

  • 这就是我要发布的答案.但是要添加一件事,取决于所使用的编程语言,你想要的答案是-3.在VB中,True = -1. (2认同)

Not*_*bug 11

为了至少检查n了所有的Boolean条件都为真,(n必须小于或等于的总数量Boolean:P)

if (((a ? 1:0) + (b ? 1:0 ) + (c ? 1:0) + (d ? 1:0 )) >= n) {
    // do the rest
}
Run Code Online (Sandbox Code Playgroud)

编辑:@ Cruncher的评论之后

检查boolean4中的3 个

if (((a ? 1:0) + (b ? 1:0 ) + (c ? 1:0) + (d ? 1:0 )) == 3) {
    // do the rest
}
Run Code Online (Sandbox Code Playgroud)

另一个 :

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

  • @Wolf这个问题属于StackUnderflow.com:p (2认同)

dur*_*rum 11

((a xor b) xor (c xor d)) and ((a or b) and (c or d))
Run Code Online (Sandbox Code Playgroud)

第一个表达式搜索4中的1或3个true.第二个表达式从4中消除0或1(有时是2)true.


Dav*_*rad 11

Java 8,过滤掉false值,并计算剩余的真值:

public static long count(Boolean... values) {
    return Arrays.stream(values).filter(t -> t).count();
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用它如下:

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

容易推广到检查nm项目是真实的.


Tim*_* S. 10

这是使用LINQ在C#中解决它的方法:

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


Pau*_*aul 10

那就是对称布尔函数S?(4).对称布尔函数是一个布尔函数,它只取决于输入的数量,但不取决于它们是哪个输入.Knuth在"计算机编程艺术"第4卷第7.1.2节中提到了这种类型的功能.

S?(4) 可以使用以下7个操作计算:

(x && y && (a || b)) ^ ((x || y) && a && b)
Run Code Online (Sandbox Code Playgroud)

Knuth表明这是最优的,这意味着你不能使用普通的运算符在少于7次的操作中执行此操作:&&, || , ^, <,>.

但是,如果要在1用于true和0false 的语言中使用它,您还可以轻松地使用添加:

x + y + a + b == 3
Run Code Online (Sandbox Code Playgroud)

这让你的意图很清楚.


Cru*_*her 9

(a && b && (c xor d)) || (c && d && (a xor b))
Run Code Online (Sandbox Code Playgroud)

从纯逻辑的角度来看,这就是我想出的.

根据鸽子洞的原则,如果确切的是3,那么a和b都是真的,或者c和d是真的.然后,只需要将其中每一个案件与其他案件中的一个完全相关.

Wolfram真相表


Rol*_*olf 8

如果您使用像Karnaugh Maps这样的逻辑可视化工具,您会发现这是一个问题,如果您想在一个if(...)行中编写它,就无法避免完整的逻辑术语.Lopina已经展示了它,不可能把它写得更简单.您可以稍微考虑一下,但是对于您和机器而言,它将难以阅读.

计数解决方案并不坏,它们展示了您真正追求的目标.如何有效地进行计数取决于您的编程语言.使用Python oder LinQ的数组解决方案很好看,但要注意,这是缓慢的.Wolf(a + b + x + y)== 3可以很好地运行,但只有当你的语言与"1"等于"真"时才是如此.如果"true"用-1表示,你将需要测试-3: )

如果你的语言使用真正的布尔值,你可以尝试明确地编程它(我使用!=作为XOR测试):

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
}
Run Code Online (Sandbox Code Playgroud)

"x!= y"仅在x,y属于布尔类型时有效.如果它们是其他类型,其中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;
Run Code Online (Sandbox Code Playgroud)

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

return a ? (b ? (x != y) : (x && y)) : (b ? (x && y) : false);
Run Code Online (Sandbox Code Playgroud)

这段代码完成了三个逻辑测试(a的状态,b的状态,x和y的比较),并且应该比这里的大多数其他答案更快.但是你需要对它进行评论,否则你将在3个月后理解它:)


Ale*_*x D 8

这里有很多好的答案; 这是另一个尚未发布的替代配方:

 a ? (b ? (c ^ d) : (c && d)) : (b && c && d)
Run Code Online (Sandbox Code Playgroud)


La-*_*eja 7

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

int t(boolean b) {
    return (b) ? 1 : 0;
}

if (t(x) + t(y) + t(a) + t(b) == 3) return true;
return false;
Run Code Online (Sandbox Code Playgroud)

我更喜欢将它们计为整数,因为它使代码更具可读性.


Aar*_*all 7

Python中,要查看一个可迭代元素中有多少是True,请使用sum(它非常简单):

建立

import itertools

arrays = list(itertools.product(*[[True, False]]*4))
Run Code Online (Sandbox Code Playgroud)

实际测试

for array in arrays:
    print(array, sum(array)==3)
Run Code Online (Sandbox Code Playgroud)

产量

(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
Run Code Online (Sandbox Code Playgroud)


ior*_*vic 5

如果您正在使用纸上(非编程)解决方案,那么K-maps和Quine-McCluskey算法就是您所追求的,它们可以帮助您缩小布尔函数.

在你的情况下,结果是

y = (x?3 ^ x2 ^ x1 ^ x0) ? (x3 ^ x?2 ^ x1 ^ x0) ? (x3 ^ x2 ^ x?1 ^ x0) ? (x3 ^ x2 ^ x1 ^ x?0)
Run Code Online (Sandbox Code Playgroud)

如果你想以编程方式执行此操作,非固定数量的变量和自定义"阈值",那么简单地通过布尔值列表迭代并计算"true"的出现次数非常简单明了.

  • @NameSpace它是人们用来表达"不"的IMO太多符号之一. (3认同)

Wol*_*olf 5

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

给定4个布尔值a,b,x,y,此任务转换为以下C语句:

return (a+b+x+y) == 3;
Run Code Online (Sandbox Code Playgroud)