2

我注意到我的编码有些未定义。假设我们有一个二维数组、一个矩阵或一个表,我们正在查看它以检查每个行或嵌套维度的属性是否为真。

假设我有一个布尔标志,用于检查属性是真还是假。我的选择是:

  1. 将其初始化为 true 并检查每个单元格,直到证明为 false。在代码完全执行之前,这会给它一个错误的名称。
  2. 从 false 开始并检查每一行,直到证明为 true。只有当所有行都为真时,数据才会正确。没有柜台的最干净的方法是什么?

我总是不假思索地做了1,但今天它让我想知道。2呢?

4

6 回答 6

12

恕我直言,取决于哪个先将您从循环中转储。

例如,在 OR 情况下,我默认为 false,一旦你得到一个 TRUE,就返回结果,否则在循环失败时返回默认值。

对于 AND 情况,我会做相反的事情。

于 2009-04-28T00:22:08.727 回答
3

它们实际上都等同于同一件事,并且由于您说“检查每个行或嵌套维度的属性是否为真”,我相信第一种方法更容易阅读并且可能稍微快一些。

在代码完全执行之前,您不应该尝试读取标志的值,因为检查还没有完成。如果您正在运行异步代码,则应防止在不稳定时访问该值。

在执行代码之前,这两种方法都“给出了错误的名称”。1 给出假阳性,2 给出假阴性。我不确定你这样说是想避免什么——如果你能在完全运行你的代码之前获得“正确”的值,那么你一开始就没有运行你的代码。


如何在没有计数器的情况下实现每个(如果您的语言没有foreach语法,请使用适当的enumerator->next循环语法):

1:

bool flag = true;

foreach(item in array)
{
    if(!check(item))
    {
        flag = false;
        break;
    }
}

2:

bool flag = false;
foreach(item in array)
{
    if(!check(item))
    {
        break;
    } 
    else if(item.IsLast())
    {
        flag = true;
    }
}
于 2009-04-28T00:30:45.463 回答
2

选择第一个选项。算法总是有前置条件、后置条件和不变量。如果您的不变量是“如果 0-currentN 中的所有行都具有正属性,则 bool x 为真”,那么一切都很好。

不要仅仅为了使整个程序状态在每行迭代中有效而使您的算法更复杂。重构方法,提取它,并使用您的语言机制(Java:)使其“原子化” synchronized

于 2009-04-28T00:34:58.697 回答
1

就个人而言,我只是将整个循环放入一个名为 isPropertyAlwaysTrue(property, array[][]) 的有点可重用的方法/函数中,如果发现它发现不正确的情况,则直接返回 false。

顺便说一句,逻辑倒置不会让你更快地离开那里。例如,如果您想要第一个不正确的情况,说 areAnyFalse 或 areAllTrue 将有一个反转的输出,但必须测试完全相同的情况。

areAnyTrue 和 areAllFalse 也是这种情况——完全相同算法的不同词(一旦找到真值就返回)。

您无法将 areAnyFalse 与 areAnyTrue 进行比较,因为它们正在测试完全不同的情况。

于 2009-04-28T00:30:25.480 回答
0

使属性名称类似于isThisTrue. 然后它会回答“是”或“否”,但它总是有意义的。

在 Ruby 和 Scheme 中,您可以在名称中使用问号:isThisTrue?. 在许多其他语言中,名称上都有一个将“p”表示为“谓词”的约定——null-p用于在 LISP 中返回真或假的测试。

于 2009-04-28T00:21:10.367 回答
0

我同意 Will Hartung 的观点。

如果您担心(1),那么只需为您的布尔值选择一个更好的名称。IsNotSomething 而不是 IsSomething。

于 2009-04-28T00:27:30.290 回答