So I have a for
loop that looks like this:
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
is ArrayList with words (strings) in it, let's say it looks like this:
[aabb, aabc, abab, abba, abcd, bbaa, cbad]
and isAnagram
returns true
or false
if two given strings are anagrams or not.
I'm trying to make it add all anagrams for each word to to one string so it would look like that:
[aabb abab abba bbaa, aabc, abcd cbad]
and right now I'm getting:
[aabb abab, aabc, abba bbaa, abcd cbad]
So what i think is happening - the second for
ends whenever it finds first anagram for al.get(i)
and than it breaks and goes for next i
. Can someone explain why this happens?
Your list:
[aabb, aabc, abab, abba, abcd, bbaa, cbad]
When j=2
, you will be looking at abab
. You find that it's an anagram, so you modify the earlier element and remove abab
. Here's what your list now looks like:
[aabb abab, aabc, abba, abcd, bbaa, cbad]
There are now 2 problems. First, "abba"
used to be al.get(3)
, but now it's al.get(2)
. But when you loop back, you increment j
, so j
is now 3. The result is that your code never looks at "abba"
.
The other problem is that even if your code did look at "abba"
, it would not find that it's an anagram. This is because you've destroyed the string you were comparing it to, i.e. al.get(i)
where i==0
. This string was "aabb"
, but now it's "aabb abab"
. So your logic will no longer work.
There are two things you'll need to do:
(1) Rearrange your loop so that you do not increment j
when you remove an element; you increment j
only when you don't remove it. Personally, I'd use a while
loop instead of a for
loop to accomplish this. [For what it's worth, I don't like the practice of modifying the index variable that you're using in a for
loop; I think makes code less readable, because to me the usual for
loop with j++
as the third part looks like you're going to execute the body for every integer in a sequence, and modifying j
in the middle of the loop contradicts that appearance. Others think it's OK, though.]
(2) Don't modify al.get(i)
(that is, don't call al.set(i,new value)
) until you no longer need it in your anagram checks, i.e. when the inner loop is completed. You'll have to declare a variable to hold the new string, and then call al.set
later.