28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)
题目都无需理解了,就以该题为模板学下kmp算法,这里我用的是Kmp算法的优化版
1、建立nextval数组
我们令初始的数组下标为-1,如果i,j代表字符相等,就令下一位更新。如果i++,j++后对应的字符相同,就将pi[j]转移给pi[i],避免重复讨论;如果不相等,就直接令pi[i]=j就好。
2、字符串匹配
直接逐个比较,相等就++,不等j就进行转移,如果存在j遍历完的情况,返回对应i的下标即可。
class Solution {
public:
int strStr(string haystack, string needle) {
int m=haystack.size(),n=needle.size();
vector<int> pi(n,0);
pi[0]=-1;
int i=0,j=-1;
while(i<n-1){//只用n-2进入即可,因为会++达到n-1
if(j==-1 || needle[i]==needle[j]){
i++,j++;
if(needle[i]!=needle[j]) pi[i]=j;
else pi[i]=pi[j];
}else j=pi[j];
}
i=0,j=0;
while(i<m && j<n){ //注意j可能为-1,所以如果要写 j<s2.size(),注意变成有符号数再比较,
即j<(int)s2.size()
if(j==-1 || haystack[i]==needle[j]){
i++,j++;
}else j=pi[j];
if(j==n) return i-n;
}
return-1;
}
};