KMP算法(改进的模式匹配算法)——next函数

KMP算法简介

KMP算法是在基础的模式匹配算法的基础上进行改进得到的算法,改进之处在于:每当匹配过程中出现相比较的字符不相等时,不需要回退主串的字符位置指针,而是利用已经得到的部分匹配结果将模式串向右“滑动”尽可能远的距离,再继续进行比较。在KMP算法中,依据模式串的next函数值实现字串的滑动,本随笔介绍next函数值如何求解。

next[ j ]求解

将 j-1 对应的串与next[ j-1 ]对应的串进行比较,若相等,则next[ j ]=next[ j-1 ]+1;若不相等,则将 j-1 对应的串与next[ next[ j-1 ]]对应的串进行比较,一直重复直到相等,若都不相等则为其他情况

题1

在字符串的KMP模式匹配算法中,需先求解模式串的函数值,期定义如下式所示,j表示模式串中字符的序号(从1开始)。若模式串p为“abaac”,则其next函数值为()。

 

 

 

 

解:j=1,由式子得出next[1]=0;

j=2,由式子可知1<k<2,不存在k,所以为其他情况即next[2]=1;

j=3,j-1=2 对应的串为b,next[2]=1,对应的串为a,b≠a,那么将与next[next[2]]=0对应的串进行比较,0没有对应的串,所以为其他情况,也即next[3]=1;

j=4,j-1=3 对应的串为a,next[3]=1,对应的串为a,a=a,所以next[4]=next[3]+1=2;

j=5,j-1=4 对应的串为a,next[4]=2,对应的串为b,a≠b,那么将与next[next[4]]=1对应的串进行比较,1对应的串为a,a=a,所以next[5]=next[2]+1=2;

综上,next函数值为 01122。

 

题2

在字符串的KMP模式匹配算法中,需先求解模式串的函数值,期定义如下式所示,j表示模式串中字符的序号(从1开始)。若模式串p为“tttfttt”,则其next函数值为()。

 

 

 

 

解: 

j=1,由式子得出next[1]=0;

j=2,由式子可知1<k<2,不存在k,所以为其他情况即next[2]=1;

j=3,j-1=2 对应的串为t,next[2]=1,对应的串为t,t=t,所以next[3]=next[2]+1=2;

j=4,j-1=3 对应的串为t,next[3]=2,对应的串为t,t=t,所以next[4]=next[3]+1=3;

j=5,j-1=4 对应的串为f,next[4]=3,对应的串为t,f≠t,那么将与next[next[4]]=2对应的串进行比较,2对应的串为t,f≠t。继续和next[2]=1对应的串对比,序号为1也就是第一个串对应的串为t,同样f≠t,到此所以对比已结束,均不相等,所以为其他情况,next[5]=1;

j=6,j-1=5 对应的串为t,next[5]=1,对应的串为t,t=t,所以next[6]=next[5]+1=2;

j=7,j-1=6 对应的串为t,next[6]=2,对应的串为t,t=t,所以next[7]=next[6]+1=3;

综上,next函数值为0123123。

最后附上求模式串的next函数,如下

 *求模式串p的next函数值,并存入数组next

void Next(char *p,int next[])
{
 int i,j,len;
 len=strlen(p);
 i=0;
 next[0]=-1;
 j=-1;
 while(i<len)
 {
  if(j==-1||p[i]==p[j]){++i;++j;next[i]==j;}
  else j=next[j];
 }
}

 

posted @ 2021-04-21 14:02  飏大神  阅读(1363)  评论(0编辑  收藏  举报