代码随想录第9天| KMP
KMP思路:求前缀表
找模式串t中的最长相等前后缀:
前缀:以第1个字符开头,不包含最后一个字符的连续子串;
后缀:以最后一个字符结尾,不包含第1个字符的连续子串
我的代码next数组就是前缀表,没有右移,也没有-1.
当字符串不匹配时,寻找前一位置的next数组值,跳转过去。
getNext函数中,
j:是前缀末尾,也是最长相等前后缀的长度
i: 要求的当前位置next[i],是后缀的末尾
相当于[0, j]与[1,i]做模式匹配,不匹配则跳转到前一位的next数组,不匹配再跳转,直到匹配或者j=0。
class Solution {
public:
void getNext(const string &s, vector<int> & next){
// j:前缀末尾,最长相等前后缀的长度
// i:要求的当前位置next[i],后缀的末尾
int j = 0;
for(int i = 1; i < s.size(); i++){
while(j > 0 && s[j] != s[i])
j = next[j - 1]; // 相当于[0, j]与[1,i]模式匹配,不匹配则跳转到前一位的next数组
if(s[j] == s[i])
j++; // 相等,前缀末尾+1,最长相等前后缀的长度+1
next[i] = j;
}
}
int strStr(string haystack, string needle) {
if (needle.size() == 0) {
return 0;
}
vector<int> next(needle.size(), 0);
getNext(needle, next);
int i = 0, j = 0;
for(;i < haystack.size(); i++){
while(j > 0 && haystack[i] != needle[j])
j = next[j - 1];
if(haystack[i] == needle[j])
j++; // j是匹配的长度
if(j == needle.size())
return (i - needle.size() + 1);
}
return -1;
}
};