KMP算法

一、算法的功能:

主字符串: ababcababababcab
模式串: abababab

判断在主串中是否存在模式串,如果存在,在哪个位置。

二、算法的思想:

        设模式串为“P0...Pm-1",KMP匹配算法的思想是:当模式串中的字符Pj与主串中相应的字符Si不相等时,因其前j个字符(“P0...Pj-1”)已经获得了匹配,所以若模式串中的

“P0...Pk-1”与“Pj-k...Pj-1”相同,这时可令Pk与Si进行比较,从而使i无须回退。在KMP算法中,依据模式串的next函数值实现子串的滑动。若令next[j]=k,则next[j]表示当模式串

中的Pj与主串中相应字符不相等时,令模式串的Pk与主串的相应字符进行比较。

三、next数组

        next函数的定义如下:

                 

求next函数值的算法如下:

void get_next(char T[],int next[]){
       int j = 1,k = 0;
       next[1] = 0;
       while(j<=T[0]){                //T[0]用于保存字符串的长度
               if(k==0||T[j]==T[k]){
                       ++j;++k;next[j]=k;     
              }
              else
                       k=next[k];
      }
}

手工求解next数组的方法:

(1)next[1]=0,next[2]=1(next[0]不使用)

(2)后面求解每一位的next[j]值时,根据j的前一位进行比较,令k=next[j-1];

(3)比较S[j-1]与S[k]进行比较:

          a.如果相等,则该next[j]=k+1;

          b.如果不相等,令k=next[k],若k不等于0,跳到(3);若k等于0,则next[j]=1。

例如模式串S=‘abaabcac’,依照以上算法求next数组:

(1)next[1]=0,next[2]=1

编号12345678
Sabaabcac
next01      

(2)当j=3,此时k=next[j-1]=next[2]=1,比较S[2]与S[k](S[1])不等,此时k=next[k]=0,所以next[3]=1。

(3)当j=4,此时k=next[3]=1,比较S[3]与S[k](S[1])相等,所以next[4]=k+1=1+1=2。

(4)当j=5,此时k=next[4]=2,比较S[4]与S[k](S[2])不等,此时k=next[k]=next[2]=1,继续比较S[4]与S[k](S[1])相等,所以next[5]=S[k]+1=1+1=2。

(5)当j=6,此时k=next[5]=2,比较S[5]与S[k](S[2])相等,所以next[6]=k+1=2+1=3。

(6)当j=7,此时k=next[6]=3,比较S[6]与S[k](S[3])不等,此时k=next[k]=next[3]=1,继续比较S[6]与S[k](S[1])不等,此时k=next[k]=0,所以next[7]=1。

(7)当j=8,此时k=next[7]=1,比较S[7]与S[k](S[1])相等,所以next[8]=k+1=1+1=2。

最终求的next数组如下所示:

编号12345678
Sabaabcac
next01122312

四、进行主串和模式串的匹配

代码如下:

int KMP(char S[],char T[],int next[],int pos){
	i=pos;
	j=1;
	while(i<=S[0]&&j<=T[0]){
       		if(j==0||S[i]==T[j]){
			++i;
			++j;
		}
		else
			j=next[j];
	}
}






  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值