class Solution {
public:
void getNext(string ch,int length,vector<int> &next)
{
next[0] = -1;
int i=0,j=-1;//i是主串正在匹配的字符位置,j代表的是前面已经匹配成功的后一个。
while(i<length-1)
{
if(j==-1||ch[i]==ch[j]){
next[++i] = ++j;
} //若是当前的ch[i]与前面最大相匹配的后一个相等的话,就next[++i]=++j;
else j = next[j];//否则的话就去找前面的
}
}
int strStr(string haystack, string needle) {
if(needle.empty()) return 0;
int total_needle = needle.size();
int total_haystack = haystack.size();
vector<int> next(total_needle,0);//next数组
getNext(needle,total_needle,next);//next初始化
//现在开始KMP
int i=0,j=0;
while(i<total_haystack&&j<total_needle)
{
if(j==-1||haystack[i]==needle[j])
{
i++;
j++;
}
else{
//本来是要重新i变成刚刚的第二个开始的,但是显然有很多无效的,我们用next跳过就可以高效搜索了
//i = i - next[j];
//j = next[j];
//上面注释的就是这个意思,但是next[j]匹配好的没必要再比对,所以代码可以简化为
//特殊情况,一个都对不上,就j=next[0]=-1了,再上面判断这种情况就可以从j=0开始去正常判断了
j = next[j];
}
}
//最后,当全部比对上了,会j++,因此j==total_needle+1;
if(j >= total_needle)
{
return (i-total_needle);
}
else
return -1;
}
};
力扣28.实现strStr()的KMP实现
最新推荐文章于 2024-05-22 09:22:48 发布