I do code in C#. I see two problems, one of which was already pointed out:
static int find(string term, string text)
{
int found = -1;
int termIndex = 0;
//quick check to protect the user from themselves
if(String.IsNullOrEmpty(term) || string.IsNullOrEmpty(text))
return -1;
for (int textIndex = 0; textIndex < text.Length; textIndex++)
{
if (term[termIndex] == text[textIndex])
{
//assign the index first, then return it
if (termIndex == 0)
found = textIndex;
//because we assign found to a *possible* match,
//we must be sure that we have a real match before returning
//so this is the ONLY place where we should return "found".
termIndex++;
if (termIndex >= term.Length)
return found;
}
else
{
termIndex = 0;
//If a match fails, revert to the start of the attempted match.
//the for loop will increment it to the next character
if(found >= 0)
textIndex = found;
found = -1;
}
}
//if we get here, the substring was not found in its entirety,
//regardless of the value of "found".
return -1;
}
The first major fix in the if
block makes sure that found
has the proper index in the case of a one-character match; If the first character matches the single-character substring, we'd immediately return -1 because found
was never initialized. However, if we do this, then we run the risk of finding a possible match at the end of the string, running out of characters, and incorrectly returning the index of the partial match. For example, find("aaa", "aabaa")
would return index 3 when term
doesn't actually exist, because it looked like a match until we ran out of characters. So, we must change the default return value to -1, and must only return the index of a possible match once we confirm that it really is a match, because if we run out of characters in text
before we successfully reach the end of term
, then term
doesn't exist in text
.
The second fix in the else
block makes sure that multi-character substrings aren't overlooked in cases where one substring seems to match but then doesn't, but the substring starting on the very next character of text
would match. For instance, find("aabaa", "aaabaa")
would fail with your initial implementation, because after the algorithm found the first two 'a's, it would search for 'b' and not find it, discard that match, but then continue at index 3, when the substring starting at index 1 would have matched. Now, this does change the index of the counter variable in the for loop, which some might say is a no-no, but I see no problem with it; it's exactly the behavior that the algorithm should exhibit.
Finally, up at the very top, if term
or text
had been null, the function would have thrown a NullReferenceException. If term
had been empty, same thing. text
being empty would have worked (text.Length
would be zero and so we'd never enter the loop), but it's easy with String.INOE() to check both at once.
text.indexOf(term)
? \$\endgroup\$ – jackwanders Jul 12 '12 at 20:28indexOf()
would use. \$\endgroup\$ – W.K.S Jul 12 '12 at 20:39