为什么循环制动比它应该的早?
Why does for loop brake earlier than it should?
所以我有一个看起来像这样的 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
returns true
或 false
如果两个给定的字符串是否是变位词。
我试图让它将每个单词的所有字谜添加到一个字符串中,所以它看起来像这样:
[aabb abab abba bbaa, aabc, abcd cbad]
现在我得到:
[aabb abab, aabc, abba bbaa, abcd cbad]
所以我认为正在发生的事情 - 第二个 for
在找到 al.get(i)
的第一个变位词时结束,然后中断并继续下一个 i
。有人可以解释为什么会这样吗?
您的列表:
[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
循环:
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
returns true
或 false
如果两个给定的字符串是否是变位词。
我试图让它将每个单词的所有字谜添加到一个字符串中,所以它看起来像这样:
[aabb abab abba bbaa, aabc, abcd cbad]
现在我得到:
[aabb abab, aabc, abba bbaa, abcd cbad]
所以我认为正在发生的事情 - 第二个 for
在找到 al.get(i)
的第一个变位词时结束,然后中断并继续下一个 i
。有人可以解释为什么会这样吗?
您的列表:
[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
。