I wanna make a summary for KMP.
Next[j] means that max{ Next[j]| needle[j-Next[j]..j-1] == needle[0..Next[j]-1] }, i.e., at most k characters before needle[j] are matching the first k characters of needle(needle[0..k-1]), i.e., if (haystack[i] != needle[j]) at least haystack[i-j..i-1] == needle[0..j-1] and needle[0..next[j]-1] == needle[j-next[j]..j-1], so in the next turn, we should compare haystack[i] and needle[ next[j] ] to determine whether bring forward i and j. The array next is also calculated by this way. The following is the code.
class Solution {
public:
char *strStr(char *haystack, char *needle) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if (needle == NULL || haystack == NULL)
return NULL;
int i = 0, j = -1, needlelen = strlen(needle), haystacklen = strlen(haystack);
if (needlelen > haystacklen)
return NULL;
if (needlelen == 0)
return haystack;
vector<int> next(needlelen+1, -1);
while (needle[i]) {
if (j == -1 || needle[i] == needle[j]) {
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
i = 0;
j = 0;
while (haystack[i]) {
if (j == -1 || haystack[i] == needle[j]) {
++i;
++j;
if (needle[j]=='\0')
return haystack+i-j;
}
else
j = next[j];
}
return NULL;
}
};
Meanwhile, there's another improvement for this code. For example,
The following is obviously better.
The code after improvement is :
class Solution {
public:
char *strStr(char *haystack, char *needle) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if (needle == NULL || haystack == NULL)
return NULL;
int i = 0, j = -1, needlelen = strlen(needle), haystacklen = strlen(haystack);
if (needlelen > haystacklen)
return NULL;
if (needlelen == 0)
return haystack;
vector<int> next(needlelen+1, -1);
while (needle[i]) {
if (j == -1 || needle[i] == needle[j]) {
++i;
++j;
if (needle[i] != needle[j])
next[i] = j;
else
next[i] = next[j];
}
else
j = next[j];
}
i = 0;
j = 0;
while (haystack[i]) {
if (j == -1 || haystack[i] == needle[j]) {
++i;
++j;
if (needle[j]=='\0')
return haystack+i-j;
}
else
j = next[j];
}
return NULL;
}
};