kmp算法:KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。
给出一个串:abacabcab,相应的next[]={-1,0,0,1,0,1,2,0,1};next[i]可以理解为当前字符以前的串中最长的相同的前缀和后缀的长度。
得到next数组代码
void getnext(char *a,int len)
{
int i=0,j=-1;
nextt[i]=j;
while(i<len)
{
if(j==-1||a[i]==a[j])
{
i++;
j++;
nextt[i]=j;
}
else
{
j=nextt[j];
}
}
}
kmp写法:
bool kmp(char *a,char *b,int lena,int lenb)
{
int i=0,j=0;
while(i<lenb)
{
if(j==-1||a[j]==b[i])
{
i++;
j++;
if(j==lena)
{
return true;
}
}
else
{
j=nextt[j];
}
}
return false;
}
匹配过程如上
next数组应用
1:求最大循环节
if(lena%(lena-next[lena])==0)
{
printf("%d\n",lena/(lena-next[lena]));
}
2:求最大循环次数
void kmp(int x)
{
int i=0,j=0;
while(i<x)
{
if(j==-1||str1[j]==str2[i])
{
i++;j++;
if(j==len1)
{
sum++;
}
}
else
{
j=next[j];
}
}
}
例题:poj 2406,poj 2752,poj 3080,poj 3450,poj 3461.