如何重新调整病情使其好转?


35

我有病

if(exists && !isDirectory || !exists)
{}

我该如何修改它,以便使其更容易理解。


1
isDirectory在存在时具有什么值是false?
marktani 2012年

1
存在是布尔类型,isDirectory也是布尔类型变量
Spynet

5
if(!isDirectory)...(存在||!存在)将始终为true。
鲨鱼2012年

@Shark-如果existsisDirectory都为真怎么办?
pasawaya 2012年

我将标题读为“我有一个人格问题,我能省掉修理的心”。是的,我很累。
安南2012年

Answers:


110

|| 是可交换的

if(!exists || (exists && !isDirectory))

是等效的。

现在,因为存在在第二部分中始终为真,||您可以删除&&

if(!exists || !isDirectory)

或者,您可以进一步执行以下操作:

if(!(exists && isDirectory))

5
这里暗示但未明确提及的是,&&它的优先级更高(至少在大多数众所周知的语言中,可能会有例外)||。因此a && b || c等同于(a && b) || c但不等同于a && (b || c)
彼得Török

27
我认为,这!exists || !isDirectory更“可以理解”,因为isDirectoryif不能成立!exists。因此,作为一个人类,我们将说“如果它不存在或[存在并且它]不是目录”。
duros 2012年

6
我更喜欢!存在|| 最后一个!isDirectory。
2012年

3
||仅在用于无副作用的值上时才是可交换的-例如,如果与函数一起使用,则某些函数可能不会被调用(短路)或以不同的顺序返回不同的值。
orlp 2012年

26
任何依靠'&&','||','==','!='等相对优先级,并且没有使用方括号来表明意图的人都应该被枪杀。在所有语言中,例如'a && b || c'相当于一条评论,说作者可能在匆忙中把整个事情搞砸了,以避免输入一些额外的字符。
布伦丹2012年

51

作为一个过程,我建议建立一个真值表:

e = exists
d = isDirectory

e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0

这与NAND操作匹配,该操作很简单:

!(exists && isDirectory)

如果您不记得所有的逻辑门,那么Wikipedia可以很好地引用要启动的真值表


@ChristofferHammarström提出了关于isDirectory被捆绑到的状态的重要观点exists。假设它们引用相同的引用,并且不可能具有该引用不存在为目录的状态,则真值表可以编写如下:

e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0

n/a被用于表示没关系的状态。可接受的减少可能导致10导致的状态n/a

考虑到这一点,!(exists && isDirectory)仍然是有效的减少,导致1!e && d

但是,!isDirectory这将是一个简单得多的减少,导致0!e && d


4
下一步是要认识到isDirectory依赖exists。它既不能是目录,也不能存在。
ChristofferHammarström,2012年

@ChristofferHammarstrom,在上下文之外,我不能假设变量引用的是同一件事,但这是有效的观点。结果列应填充n/a在无法实现状态的位置,并且方程式相应减少。
zzzzBov 2012年

好吧,如果变量引用两个不同的上下文,那么它们太简洁了,需要重命名。
ChristofferHammarström,2012年

但是建立真值表并对其进行评估是NP完整的!
Thomas Eding 2012年

@ThomasEding,然后为您提供两句话:“理论上,理论和实践是相同的;实际上,它们是不一样的。” 和“过早的优化是万恶之源。”
zzzzBov 2012年

22

为了提高可读性,我喜欢将布尔条件提取到方法中:

if(fileNameUnused())
{...}

public boolean fileNameUnused() {
   return exists && !isDirectory || !exists;
}

或使用更好的方法名称。如果可以正确地命名此方法,则代码的阅读者无需弄清楚布尔条件的含义。


+1说些有用的名字。但是在某个地方,您将不得不重新格式化条件代码。
Apoorv Khurasia 2012年

4
仍然传达意图的一个不太极端的替代方案只是命名使用的条件:boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
2012年

8

你可以只尝试钉不走的情况和解救如果出现。

while(someCondition) {

    if(exists && isDirectory)
        continue;
        // maybe "break", depends on what you're after.

        // the rest of the code
}

甚至

function processFile(someFile)
{ 
    // ...
    if(exists && isDirectory)
       return false;
    // the rest of the code
    // ...
}

难道不中断,继续执行,并且超过一个返回语句被认为具有代码气味吗?
Freiheit 2012年

8
@Freiheit取决于上下文。有时,可以使用早期返回语句来减少缩进,从而提高可读性。
marco-fiset 2012年

最佳答案-复杂的条件浪费大量时间阅读和准确理解它们。结果,经常被“视为已读”,从而导致隐患。
mattnz

6

您可以使用所指出的真值表。第二步可能是用于最小化术语数量的KV地图

使用布尔代数定律是另一种方法:

A =存在
B =!isDirectory
!A =!存在

&& = *
|| = +

[编辑]
一个更简单的转换,因为操作AND和OR是相互分配的:

存在&&!isDirectory || !exists
= A * B +!A
=(A +!A)*(B +!A)
= 1 *(B +!A)
= B +!A
[/编辑]

存在&&!isDirectory || !exists
= A * B +!A
= A * B +!A * 1 //身份
= A * B +!A *(B + 1)//歼灭者
= A * B +!A * B +!A / /分配和标识
= B *(A +!A)+!A //分配
= B * 1 +!A //补码2
= B +!A //标识
=!isDirectory || 存在

或使用双补码(!! x = x):

A * B +!A
= !!(A * B +!A)
=!(!(A * B)* A)
=!((!A +!B)* A)
=!(!A * A + !B * A)
=!(0 +!B * A)
=!(!B * A)
= B +!A
=!isDirectory || 存在


+1用于使用正式规则(我从没念过大学一年级就可以看到其中之一)。
Nemanja Boric



1

如前所述,该条件可以减少为:

if (!(exists && isDirectory))

但是,我敢打赌,目录意味着存在。如果是这样,我们可以将条件减少为:

if (!isDirectory)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.