所以我有一个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
会返回true
或false
。
我试图让它为每个单词添加所有字谜到一个字符串,所以看起来像这样:
[aabb abab abba bbaa, aabc, abcd cbad]
现在我得到了:
[aabb abab, aabc, abba bbaa, abcd cbad]
所以我认为正在发生的事情 - 第二个for
每当找到al.get(i)
的第一个字谜时就会结束,而不是它突破并进入下一个i
。有人可以解释为什么会这样吗?
答案 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)
。