在字符串中寻找子串并返回字符串的下标,基本思路是当我们一个个匹配字符的时候,当发现某个字符不匹配的时候,由于已经知道之前遍历过的字符,利用这些字符来避免暴力算法中回退的步骤。
重点是定义这个next数组,用来存储各个字符如果发生不匹配情况时的回退信息,KMP算法在匹配失败的时候回去看最后一个匹配的字符它所对应的next数值,比如说是2,那么就会直接跳过匹配子串的前两个字符(即从下标为2的地方开始比较),
至于next数组的生成,next数组的意义是指在匹配失败的时候子串中可以跳过的字符个数,next数组的本质实际上是寻找子串中“相同最长前后缀的长度”,用递推的方法不断的利用已经掌握的信息来避免重复的运算。
代码如下
class Solution
{
public:
void get_next(string needle, int next[10005])
{
int j = 0;
for (int i = 1; i < needle.size(); i++)
{
while (j > 0 && needle[i] != needle[j])
{
j = next[j - 1];
}
if (needle[i] == needle[j])
{
j++;
}
next[i] = j;
}
}
int strStr(string haystack, string needle) {
if (needle.size() == 0) {
return 0;
}
int next[10005];
get_next(needle, next);
int j = 0;
for (int i = 0; i < haystack.size(); i++) {
while (j > 0 && haystack[i] != needle[j]) {
j = next[j - 1];
}
if (haystack[i] == needle[j]) {
j++;
}
if (j == needle.size()) {
return (i - needle.size() + 1);
}
}
return -1;
}
};