为啥 for loop 比它应该更早地刹车?

Posted

技术标签:

【中文标题】为啥 for loop 比它应该更早地刹车?【英文标题】:Why does for loop brake earlier than it should?为什么 for loop 比它应该更早地刹车? 【发布时间】:2016-02-23 19:00:08 【问题描述】:

所以我有一个看起来像这样的for 循环:

for (int i = 0; i < al.size(); i++) 
    for (int j = i + 1; j < al.size(); j++) 
        if (isAnagram(al.get(i), al.get(j))) 
            al.set(i, al.get(i) + " " + al.get(j));
            al.remove(j);
        
    

al 是包含单词(字符串)的 ArrayList,假设它看起来像这样:

[aabb, aabc, abab, abba, abcd, bbaa, cbad]

并且isAnagram 返回truefalse 如果两个给定的字符串是否是字谜。 我试图让它将每个单词的所有字谜添加到一个字符串中,所以它看起来像这样:

[aabb abab abba bbaa, aabc, abcd cbad]

现在我得到:

[aabb abab, aabc, abba bbaa, abcd cbad]

所以我认为正在发生的事情 - 第二个for 会在它找到al.get(i) 的第一个字谜时结束,然后它会中断并继续下一个i。有人可以解释为什么会这样吗?

【问题讨论】:

你不能在数组列表中删除这样的项目al.remove(j);你应该使用迭代器 删除 ul.remove(j); 后删除它并没有帮助我得到:[aabb abab, aabc, abab abba, abba bbaa, abcd cbad, bbaa, cbad] - 它仍然不能超过一个字符串的一个字谜 一种解决方案是在删除`al.remove(j);`后的if条件内插入j--; 添加 j--; 也无济于事。输出仍然是:[aabb abab, aabc, abba bbaa, abcd cbad] Put i--; insted of j--; 【参考方案1】:

您的清单:

[aabb, aabc, abab, abba, abcd, bbaa, cbad]

j=2 时,您将看到abab。您发现它是一个字谜,因此您修改了前面的元素并删除了abab。您的列表现在如下所示:

[aabb abab, aabc, abba, abcd, bbaa, cbad]

现在有 2 个问题。首先,"abba" 以前是 al.get(3),但现在是 al.get(2)。但是当你循环回来时,你增加了j,所以j现在是3。结果是你的代码永远不会看到"abba"

另一个问题是,即使您的代码确实查看了"abba",它也不会发现它是一个字谜。这是因为您已经破坏了与之比较的字符串,即al.get(i),其中i==0。这个字符串是"aabb",但现在是"aabb abab"。所以你的逻辑将不再有效。

您需要做两件事:

(1) 重新排列循环,以便在删除元素时不会增加j;仅当您不删除它时才增加j。就个人而言,我会使用while 循环而不是for 循环来完成此操作。 [无论如何,我不喜欢修改您在for 循环中使用的索引变量的做法;我认为使代码的可读性降低,因为对我来说,通常的 for 循环和 j++ 作为第三部分看起来你要为序列中的每个整数执行主体,并在中间修改 j该循环与该外观相矛盾。不过其他人认为没关系。]

(2) 不要修改al.get(i)(也就是说,不要调用al.set(i,new value)),直到在你的字谜检查中不再需要它,即当内部循环完成时。您必须声明一个变量来保存新字符串,然后再调用al.set

【讨论】:

以上是关于为啥 for loop 比它应该更早地刹车?的主要内容,如果未能解决你的问题,请参考以下文章

Bootstrap:如何更早地折叠导航栏

如何比任何其他全局或静态变量更早地创建/构造类实例?

如何让 Vertx 处理程序在事件循环中更早地执行?

为啥我的状态计数器比它应该的值落后一个值?

对为啥我的算法运行速度比它应该的慢感到困惑

附加作业