如何判断*exact*one boolean是否为真,没有类型转换?

SCd*_*CdF 23 logic boolean

鉴于布尔值的任意列表,什么是确定的最优雅的方式正是其中之一是真的吗?

最明显的黑客攻击是类型转换:将它们转换为0for false1for true,然后对它们求和,然后返回sum == 1.

我想知道是否有办法在将它们转换为int的情况下执行此操作,实际上使用布尔逻辑.

(这似乎应该是微不足道的,idk,长周)

编辑:如果不明显,这更像是一个代码高尔夫/理论问题.我不喜欢在PROD代码中使用类型转换/ int添加,我只是感兴趣,如果有没有这样做的方式.

编辑2:对不起,这是一个漫长的一周,我不是很好地解释自己.让我试试这个:

在布尔逻辑中,如果所有布尔都为真,则对一组布尔值进行AND运算是正确的,如果其中至少有一个为真,则该集合为真.如果只有一个布尔值为真,那么是否存在一个逻辑结构?例如,对于两个布尔值的集合,XOR就是这个,但不仅如此,它还会失败.

小智 8

实际上,您可以仅使用布尔逻辑来完成此操作,尽管在您的示例中可能没有实际值.布尔版本比简单计算真值的数量要多得多.

无论如何,为了满足求知欲,这里也是如此.首先,使用一系列XOR的想法很好,但它只能让我们走到一半.对于任何两个变量xy,

Xÿ

只要其中一个是真的,它就是真的.但是,如果添加第三个变量z,则不会继续如此

Xÿž

第一部分,Xÿ,仍然是正确的,如果正好一个XŸ是真实的.如果xy为真,则z必须为false才能使整个表达式为真,这就是我们想要的.但是考虑一下如果xy都为真,会发生什么.然后XŸ是假的,但如果整个表达式可以成为真正的ž是也是如此.因此,无论是一个变量还是全部三个都必须为真.通常,如果您的语句是一个XOR链,那么如果变量数量不正确,则为真.

由于一个数字不均匀,这可能证明是有用的.当然,检查不确定数量的真相是不够的.我们还需要确保只有一个变量是真的.这可以通过采用所有两个变量对并检查它们都不是真的以成对方式完成.将这两个条件组合在一起确保如果变量为真,则只有一个条件.

下面是一个小Python脚本来说明这种方法.

from itertools import product

print("x|y|z|only_one_is_true")
print("======================")
for x, y, z in product([True, False], repeat=3):
    uneven_number_is_true = x ^ y ^ z
    max_one_is_true = (not (x and y)) and (not (x and z)) and (not (y and z))
    only_one_is_true = uneven_number_is_true and max_one_is_true
    print(int(x), int(y), int(z), only_one_is_true)
Run Code Online (Sandbox Code Playgroud)

这是输出.

x|y|z|only_one_is_true
======================
1 1 1 False
1 1 0 False
1 0 1 False
1 0 0 True
0 1 1 False
0 1 0 True
0 0 1 True
0 0 0 False


Eri*_*zzo 5

当然,你可以这样做(伪代码,因为你没有提到语言):

found = false;
alreadyFound = false;
for (boolean in booleans):
    if (boolean):
        found = true;
        if (alreadyFound):
            found = false;
            break;
        else:
            alreadyFound = true;
return found;
Run Code Online (Sandbox Code Playgroud)


c.f*_*lou 5

在您澄清之后,这里没有整数。

 bool IsExactlyOneBooleanTrue( bool *boolAry, int size )
    {
      bool areAnyTrue = false;
      bool areTwoTrue = false;
      for(int i = 0; (!areTwoTrue) && (i < size); i++) {
        areTwoTrue = (areAnyTrue && boolAry[i]);
        areAnyTrue |= boolAry[i];
      }
      return ((areAnyTrue) && (!areTwoTrue));
    }
Run Code Online (Sandbox Code Playgroud)


Shi*_*mar 5

使用普通布尔逻辑,可能无法实现您想要的效果.因为您要求的是真实评估,不仅基于真值,还基于其他信息(在这种情况下计算).但是布尔评估是二进制逻辑,它不能依赖于操作数本身的其他任何东西.并且没有办法进行逆向工程以找到给定真值的操作数,因为可以有四种可能的操作数组合但只有两种结果.给定一个假,你可以判断它是否是因为你的情况下的F ^ F或T ^ T,以便可以根据这个来确定下一个评估?


TWi*_*Rob 5

没有人提到我们正在寻找的这种“操作”是类似于大多数语言中的布尔 AND 和 OR 的快捷方式。这是 Java 中的一个实现:

public static boolean exactlyOneOf(boolean... inputs) {
    boolean foundAtLeastOne = false;
    for (boolean bool : inputs) {
        if (bool) {
            if (foundAtLeastOne) {
                // found a second one that's also true, shortcut like && and ||
                return false;
            }
            foundAtLeastOne = true;
        }
    }
    // we're happy if we found one, but if none found that's less than one
    return foundAtLeastOne;
}
Run Code Online (Sandbox Code Playgroud)