如何对KMP算法有一个深入的理解,建议读者自己拿纸笔画画来切入了解
### - 理解KMP算法
- 对next数组的理解
1. 什么是next数组:next数组是在字符串pat进行匹配失败时指导用pat的哪个字符进行下一次匹配
2. 其中k代表后缀,j代表前缀
3. 具体流程如下
当`|k==-1||pat[k]==pat[j]`时,i、k++指向后缀的下一个,j++指向前缀的下一个,而让next[j]=k,就是当字符串在第j个字符匹配失败时,引导下一次匹配用pat的第k个字符继续进行匹配
当`pat[k]!=pat[j]`时,k退回到应该进行匹配的字符处(保存在next数组中)
- KMP算法
在理解next数组之后再来理解KMP算法就很简单了
对pat进行匹配,匹配成功则`i++,j++`否则将j退回到下一次应该匹配的字符处(通过next数组)而最后i与j的差值就是pat在txt的位置
- 代码实现
```C++
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
//目的:判断字符串pat是不是字符串txt的子串,如果是,则返回pat在txt中的首位置
string txt,pat;
int m,n,next[100002];
cin>>txt;
cin>>pat;
m=pat.length();
n=txt.length();
//生成next
next[0]=-1;
int j=0;
int k=next[j];
while(j<m-1){
if(k==-1||pat[k]==pat[j]){
k++;j++;next[j]=k;
//判断当前位置下pat相应字符是否相等
//相等,则将判断字符往后移,并且更新next->即
}
else k=next[k];
}
int i=0;
j=0;
//KMP算法
while(j<m&&i<n){
if(j==-1||txt[i]==pat[j]){
i++; j++;
}
else j=next[j];
}
if(j!=m) cout<<"-1 ">>;
else cout<<i-j;
}
```