KMP算法的next数组,存放的是子字符串(长度较小的字符串)的最长前缀后缀公共元素长度!!!
最常用的求next数组,也可以用来求字符串可能存在的循环节:
void getnext(char s[],int len){
int j=0,k=-1;
next[0] = -1;
while(j < len){
if(k == -1 || s[j] == s[k])
next[++j] = ++k;
else
k = next[k];
}
}
//1231231234
//-1 0 0 0 1 2 3 4 5 6另一种优化了的求next数组
void getnext(char s[],int len){
int j=0,k=-1;
next[0] = -1;
while(j < len){
if(k == -1 || s[j] == s[k]){
j++,k++;
if(s[j] != s[k])
next[j] = k;
else
next[j] = next[k];
}
else
k = next[k];
}
}kmp算法代码:
#include <bits/stdc++.h>
using namespace std;
const int maxx = 100010;
int next[maxx];
char s1[maxx],s2[maxx];
void getnext(char s[],int len){
int j=0,k=-1;
next[0] = -1;
while(j < len){
if(k == -1 || s[j] == s[k]){
j++,k++;
if(s[j] != s[k])
next[j] = k;
else
next[j] = next[k];
}
else
k = next[k];
}
}
int kmp(char s1[],char s2[])
{
getnext(s2,strlen(s2));
int i=0,j=0;
int l1 = strlen(s1),l2 = strlen(s2);
while(i < l1 && j < l2){
if(j == -1 || s1[i] == s2[j])
i++,j++;
else
j = next[j];
}
if(j == l2)
return i-j;
return -1;
}
int main()
{
scanf("%s",s1);
scanf("%s",s2);
cout<<kmp(s1,s2);
return 0;
}

京公网安备 11010502036488号