!a&&(a||b)简化为什么?

24

我对 !a&&(a||b) 有些困惑。如果我直接看并简单解释它,似乎它与以下内容相同:

!a&&a or !a&&b

但这似乎有点奇怪,因为由于a不能既是true又是false,只有在后者为true时它才会是true。我也这样解释它。


但这个解释似乎有些奇怪,因为由于变量 a 不能同时为 true 和 false,所以只有当后者为 true 时,它才会为 true。 我也这样理解它。
!a || a&&b

我真的不知道我是怎么想出这个想法的,但它看起来更合乎逻辑,因为没有矛盾。请问有人能帮我吗?


15
!a&&a 只会得到假(false),所以你只剩下 !a&&b - Benjamin Gruenbaum
5
请注意,这是建立在变量 a 的基础上的(而且它不能在计算表达式时被另一个线程修改)。如果 a 是一个方法调用,它可能会被调用两次,因此你不能总是简化它。 - ajb
2
请注意,如果ab都为真,则您的最终解释将是正确的,与原始解释不同。 - Scott Hunter
1
这个标签打错了。它与Java无关,只是关于布尔逻辑的问题。 - Sinkingpoint
1
@LieRyan:这个问题是由非提问者编辑的。原始问题明确询问了关于Java的问题,它既不纯粹也具有并发性。 - Jörg W Mittag
显示剩余10条评论
9个回答

43

重言式表

 | a | b | !a | a || b |  !a && (a || b)  | !a && b | [ !a && (a || b) ] <=> [!a && b]    |
 |---|---|----|--------|------------------|---------|-------------------------------------|
 | 0 | 0 |  1 |   0    |      0           |    0    |                   1                 |
 | 0 | 1 |  1 |   1    |      1           |    1    |                   1                 |
 | 1 | 0 |  0 |   1    |      0           |    0    |                   1                 |
 | 1 | 1 |  0 |   1    |      0           |    0    |                   1                 |
 

"证明"

  1. 根据分配律原理,语句!a && (a || b)等同于(!a && a) || (!a && b)

  2. 根据矛盾律(!a && a)等同于false

  3. 综合以上内容:

    !a && (a || b) <=> (!a && a) || (!a && b) <=> false || (!a && b) <=> !a && b


我真的很喜欢这个,但是我对最后一列感到困惑 -- 什么是 <=>?我不熟悉这个运算符...等价? - BrianH
6
是的,'<=>'代表等价(或者换句话说是双向蕴含)。 - Lukas Risko
@BrianDHall a <=> b 的意思是 (!a || b) && (!b || a) - Bakuriu
1
@Bakuriu @BrianDHall 更确切地说,它意味着 (!a || b) && (!b || a) 的计算结果为 true。这是一个明确的陈述,而不仅仅是一个命题。 - Colin P. Hill

12
您可以将其简化为 (!a && b),因为在表达式 (!a && a || !a && b) 中的条件!a && a始终为假。

11

在Java中,与大多数语言相同,一元运算符!的优先级高于&&

因此,!a&&(a||b)实际上是(!a)&&(a||b)

您可以使用卡诺图(Karnaugh map)来表示该表达式的真值表:

      | a = 0 | a = 1 |
------+-------+-------+
b = 0 |   0   |   0   |
------+-------+-------+
b = 1 |   1   |   0   |
------+-------+-------+

现在,很容易就可以看出,唯一正确的情况是(!a) && b

因此,!a&&(a||b)等同于!a && b


1 请参见下面的评论。


2
我从未见过一种语言中,NOT的优先级比ANDOR低。你见过吗? - Bergi
@Bergi 你说得对。我真是太丢脸了...在看到你的评论后,我花了至少30分钟尝试寻找一种语言,它的“非”运算符优先级低于“与”运算符。也许这样的语言存在,但我找不到。我已经编辑了我的答案,删除了那些无意义的内容。感谢你指出这个问题! - Sylvain Leroux
3
@Bergi 是的,有一种语言,叫做APL(在IBM系统上实现的那个版本)。它实际上没有任何优先级--所有运算都是从右到左。因此!A&&B实际上会被解释为!(A&&B)而不是(!A)&&B。(APL没有使用这些符号作为运算符;我记不清实际使用的符号是什么了,但可能是一些普通键盘上没有的字符)。 - ajb
@Bergi,我昨天想到了APL,但无法测试。今天早上尝试后,似乎它的行为与您解释的一样:~1∧0被计算为1--而不是0 - Sylvain Leroux
1
点赞了,这个回答比(当前的)顶部回答更加简洁。 - James Snell
@ajb:谢谢 :-) 其实我本来就预料到有这种语言没有特殊的优先级规则(像[逆]波兰符号),只是我不知道有哪种。 - Bergi

6
这句话的意思是:!a && b只有在a为false且b为true时才为true。

4

(!a && a) || (!a && b)是使用分配律的正确展开。

这可以简化为!a && b

布尔代数的分配律如下:

a && (b || c) == (a && b) || (a && c)
a || (b && c) == (a || b) && (a || c)

3

!a && (a || b)可以用二进制真值表来考虑,

a       b       out
true    true    false
false   true    true
false   false   false
true    false   false
所以唯一通过的情况是:
 (!a && b)

我们可以应用德摩根定理,得到

 !(a || !b)

3

2
如果你告诉WA(Wolfram Alpha)简化,它会直接给出结果:WA: simplify !a && (a || b) - ComFreek

2

看起来它将简化为

!a && b

如果你打开括号,你会得到

(!a && a) || (!a && b)

第一部分(!a && a)始终为假,因此可以忽略它。


2
我假设“或”运算符的优先级较低(通常布尔逻辑中的&&和||是相等的,因此这可能会产生歧义)。
  !a&&a or !a&&b
= (!a&&a) || (!a && b)
= false || (!a && b) 
      // because X and not X will never be true for any combination of X
= (!a && b)
      // because false || X == X for any value of X
= !a && b
      // removed parens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接