KMP算法

主串:"s1...sn"

子串:"p1...pm"

"p1p2...p(k-1)" = "s(i-k+1)s(i-k+2)...s(i-1)"  //上次比较了K个相同的字符

"p(j-k+1)p(j-k+2)...p(j-1)" = "s(i-k+1)s(i-k+2)...s(i-1)"  //这次比较了K个相同的字符

"p1p2...p(k-1)" = "p(j-k+1)p(j-k+2)...p(j-1)"  //这次和上次的前K个字符相同

一般地,使用next[j]表示当模式中第j个字符与主串中相应字符失配时,在模式中需重新和主串中该字符进行比较的字符的位置,即"p1p2...p(k-1)" = "p(j-k+1)p(j-k+2)...p(j-1)" 

next[j] 的取值如下:

1. j=1时,0

2. 当此集合不空时,Max{k| 1<k<j 且 "p1p2...p(k-1)" = "p(j-k+1)p(j-k+2)...p(j-1)"}

3. 其他情况,1

next[j+1]的求解过程:

模式串自身进行匹配,这里pj作为主串元素看待,pk作为子串元素看待。

1. pk = pj,即 "p1...pk" = "p(j-k+1)...pj",则next[j+1] = next[j]+1 = k+1(自身匹配,后部等于前部)

2. pk != pj,令pjpk'比较,k'=next[k](即模式未匹配时,next的用法),再比较pk'pj。若相等则next[j+1] = next[k] +1 = k'+1;否则,继续按模式未匹配处理。

void get_next(SString P, int next[]){
  next[1] = 0; next[2] = 1;
  k = 0; j = 2;
  while(j < P.length){
    k = next[j];
    if(P[j] == P[k]){
      next[j+1] = k+1; j++;
    }else{
      while(k!=0){
        if(P[j] != P[k]) k = next[k];
        else break;
      }
      next[j+1] = k+1; j++;
      }
    }
  }
}

 

化简后得

void get_next(SString P, int next[]){
  j = 1; next[1] = 0; k = 0;
  while(j < P.length){
    if(k==0 || P[j] == P[k]){
      ++j; ++k; next[j] = k;
    }else{
      k = next[k];
    }
  }
}



后通过next进行匹配即可。


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值