private static int strStr(String needle, String haystack)
{
for (int i = 0 ; ; i++)
{
for (int j = 0 ; ; j++)
{
if (j == needle.length())
{
return i;
}
if (i + j == haystack.length())
{
return -1;
}
System.out.println("needle.charAt(j) " + j + " " + needle.charAt(j));
System.out.println("haystack.charAt(i+j) " + (i + j) + " " + haystack.charAt(i+j));
if (needle.charAt(j) != haystack.charAt(i + j))
{
break;
}
}
}
}
First, let's establish a few things:
- Java starts indices at 0, so needle.charAt(0) is the first character in the string. needle.charAt(3) is the fourth character in the string.
- The line
for(int i = 0 ; ; i++)
increments i
by one through each iteration, and the for-loop will not cause the loop to stop.
It's easiest to tackle this with an example. Let's use a needle named "hip" and a haystack named "chips". Since Java indices start at 0, we would expect that the method will return 1 (representing the second character), since that's the first character of "hip" within "chips".
- When we enter the method, we go through the first for-loop.
i = 0
- The next line takes us into another for-loop.
i = 0, j = 0
j = 0
does not equal needle.length() = 3
i + j = 0 + 0 = 0
does not equal haystack.length() = 5
needle.charAt(j = 0)
is "h", haystack.charAt(i + j = 0 + 0 = 0)
is "c". Since "h" is not equal to "c", we break out of the j-for-loop. The break
keyword only breaks out of the current loop, so while we stopped executing the j for-loop, we're still within the i-for-loop.
- We start the next iteration.
i = 1
- The j for-loop restarts at 0.
i = 1, j = 0
j = 0
does not equal needle.length() = 3
i + j = 1 + 0 = 1
does not equal haystack.length() = 5
needle.charAt(j = 0)
is "h", haystack.charAt(i + j = 1 + 0 = 1)
is "h". Since these are equal, we don't break out of the j-for-loop.
- We start the next iteration of the j for-loop.
i = 1, j = 1
j = 1
does not equal needle.length() = 3
i + j = 1 + 1 = 2
does not equal haystack.length() = 5
needle.charAt(j = 1)
is "i", haystack.charAt(i + j = 1 + 1 = 2)
is "i". Since these are equal, we don't break out of the j-for-loop.
- We start the next iteration of the j for-loop.
i = 1, j = 2
j = 2
does not equal needle.length() = 3
i + j = 1 + 2 = 3
does not equal haystack.length() = 5
needle.charAt(j = 2)
is "p", haystack.charAt(i + j = 1 + 2)
is "p". Since these are equal, we don't break out of the j-for-loop.
- We start the next iteration of the j for-loop.
i = 1, j = 3
j = 3
does equal needle.length() = 3
, so we return i = 1
.
As we expected, we got 1 back from this function, since "hip" is contained within "chips" starting at position 1 (zero-indexed).
That's all well and good, but what about that i + j == haystack.length()
line?
Let's use "ben" as the needle and "bear" as the haystack (we should get back -1, since "ben" does not appear in the word "bear").
/- needle.length()
| /- haystack.length()
| | /- needle.charAt(j)
| | | /- haystack.charAt(i + j)
| | | |
i | j |n.l|h.l|n.c|h.c| result
---+---+---+---+---+---+------------------
0 | 0 | 3 | 4 | b | b | continue
0 | 1 | 3 | 4 | e | e | continue
0 | 2 | 3 | 4 | n | a | break j
1 | 0 | 3 | 4 | b | e | break j
2 | 0 | 3 | 4 | b | a | break j
3 | 0 | 3 | 4 | b | r | break j
4 | 0 | 3 | 4 | | | i + j == haystack.length(), return -1