为什么循环制动比它应该更早?

时间:2015-11-21 08:00:43

标签: java for-loop anagram

所以我有一个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。有人可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:2)

您的清单:

[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++,因为第三部分看起来像是要为序列中的每个整数执行正文,并修改{{1在循环的中间与那个外观相矛盾。其他人认为没关系。]

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