kmp算法
通过预处理出next表
将字符串匹配复杂度降为O(n+m)
在串与模式匹配的过程中 串下标永远向前走,而模式下标则通过next进行回溯比较,next[0] =-1 是特殊的位置,当回溯到-1时说明当前串与模式无法匹配,需要移动串下标
而在构造next数组的过程中 相当于进行了自身与自身的匹配 所以next数组与源串并没有关系
next数组总等于当前位置所对应的最长前缀 和 最长后缀 相同的长度 只有这样才会在转移的过程中不会遗失可能相等的地方
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
int Next[maxn];
void getNext(string str)
{
int m = str.length();
Next[0] = -1;
int j = -1;
int i = 0;
while(i<m)
{
if(j==-1 || str[i]==str[j])//如果j为-1 或能够匹配上,则将i j后移并记录Next[i] 为当前的j
{
i++,j++;
Next[i] = j;
}
else j = Next[j]; //如果匹配不上 则将j回溯
}
}
void kmp(string t,string p)
{
int i=j=0;
while(i<t.length())
{
if(j==-1||t[i]==p[j])//如果回溯到了开始 或能够匹配上 则将i,j后移
{
i++,j++;
}
else// 匹配不上 回溯j
j=Next[j];
if(j==p.length()) //已经匹配成功
{
cout << i-j+1<<endl;
j = 0; //归零j
}
}
}
int main()
{
string s1,s2;
cin>>s1>>s2;
getnext(s2);
kmp(s1,s2);
for(int i=1;i<=s2.length();++i)
cout <<Next[i] << ' ';
return 0;
}