0

为什么

while(!s1.isEmpty() && !s2.isEmpty())

while(!(s1.isEmpty() && s2.isEmpty()))

不一样吗?

因为当我这样做时 !(x&y) eclipse 给了我一个错误。
http://pastebin.com/8zBK1jQv

错误信息:

Exception in thread "main" java.lang.NullPointerException
4

5 回答 5

8

This is one of De Morgan's Law's, fundamental to Boolean algebra:

(NOT A) AND (NOT B) == NOT (A OR B)

and its converse:

(NOT A) OR (NOT B) == NOT (A AND B)

i.e, to fix your second version, you must replace the && with ||.

于 2012-12-12T16:48:22.720 回答
2

编译真值表,自己看看:

while(!s1.isEmpty() && !s2.isEmpty()):

false, false -> true
false, true  -> false
true,  false -> false
true,  true  -> false

while(!(s1.isEmpty() && s2.isEmpty())):

false, false -> true
false, true  -> true
true,  false -> true
true,  true  -> false

从上面可以看出,这两个条件的含义非常不同。

此外,由于&&短路,它们在是否s2.isEmpty()评估方面有所不同。第一个语句评估它 iff s1.isEmpty() == false,而第二个语句评估它 iff s1.isEmpty() == true)。如果s2碰巧是null,这可以决定你是否得到 a NullPointerException

于 2012-12-12T16:51:16.090 回答
2

检查此表(假设 1=true,0=false)

A|B| !A | !B | !A and !B | A and B |  not(A and B)
-+-+----+----+-----------+---------+---------------
0|0|  1 |  1 |    [1]    |    0    |      [1]
0|1|  1 |  0 |    [0]    |    0    |      [1]   <- (!A and !B)  !=  not(A and B)
1|0|  0 |  1 |    [0]    |    0    |      [1]   <- (!A and !B)  !=  not(A and B)
1|1|  0 |  0 |    [0]    |    1    |      [0]

如您所见,A=1, B=0A=0, B=1将在!A and !B和中得到不同的结果not(A and B)

让我们现在检查not(A or B)

A|B| !A | !B |[!A and !B]|  A or B |  not(A or B)
-+-+----+----+-----------+---------+---------------
0|0|  1 |  1 |    [1]    |    0    |      [1]
0|1|  1 |  0 |    [0]    |    1    |      [0]   
1|0|  0 |  1 |    [0]    |    1    |      [0]   
1|1|  0 |  0 |    [0]    |    1    |      [0]

现在您可以看到为什么!A **AND** !B可以替换为not(A **OR** B)

于 2012-12-12T17:05:07.150 回答
0

while(!s1.isEmpty() && !s2.isEmpty())
并且
while(!(s1.isEmpty() || s2.isEmpty()))
是平等的。

//注意“||”

非常重要
,尽管摩根规则表明这两个陈述在逻辑上是相同的。大多数语言只评估他们拥有的东西。因此,如果条件的任何部分有副作用或只能在其他部分有效性的情况下访问,您应该考虑部分的顺序。

于 2012-12-12T16:53:13.513 回答
0
NOT
1 -> 0    
0 -> 1

让我们说s1.isEmpty()Trues2.isEmpty()False

对于案例 1:

while(!s1.isEmpty() && !s2.isEmpty()).

然后它会像对待一样(False AND True),最终返回False。因为 和的AND运算是。TrueFalseTrue

对于案例 2:

while(!(s1.isEmpty() && s2.isEmpty())).

然后它会像对待一样(!(True AND False)),返回(!(False))Not操作False会是哪个True

于 2012-12-12T17:06:25.960 回答