学习笔记-KMP算法

KMP算法看了好几遍才慢慢搞懂,至于算法导论上用来解决相同问题的RF算法和有限状态机算法则更是云里雾里,暂且不管吧。

KMP的算法重点在于如何计算next[ ]数组的值

假设text为原字符串(t),长度为n。pattern为需要查询的字符串(p),长度为m

假设 next[i] =k ,则说明在p的第i个字符和之前,有k个字符与p最开始的k个字符重复。

比如 p = "ababacab"

可得

next [ 0 ] = 0;

next [ 1 ] = 0;

next [ 2 ] = 1;

next [ 3 ] = 2;

next [ 4 ] = 3;

next [ 5 ] = 0;

next [ 6 ] = 1;

next [ 7 ] = 2;


比较第 next[ i-1]   个数和 第 i 个数,如果相等则

next[ i ] = next [ i -1 ] + 1;

通过递推方式,可在O(m)次内计算出next数组


计算出next数组后,当比较p 中第 i 个字符,和 t 中第 s 个字符时,若不相等

查看 next[ i-1 ],若>0 则重置 i = p + next[ i-1 ],s保持不变

若 i = p 则将s = s + 1;

只需循环遍历 t 一次,即可找到匹配字符串 复杂度为 O (n)


给出代码实现,自己写的,可能不规范,仅作以后参考

int *get_next(char *p){
 int len = strlen(p);
 int *next = new int[len];
 next[0]=0;
 for(int i=1;i<len;i++){
     if((0+next[i-1] != i)&&p[0+next[i-1]] == p[i]){
        next[i] = next[i-1] + 1;
     }else if(p[0] == p[i]){
        next[i] = 1;
     }else{
        next[i] = 0;
     }
 }
 return next;
}


void find(char *t, char *p, int next[]){
   if(t==NULL || p == NULL) return;
   char *i=p;
   while(*t!='\0'){
      while(*i!='\0' && *t!='\0' && *i==*t){
        i++;
        t++;
      }
      if(*i=='\0'){
         cout<<(t-(i-p))<<endl; //输出匹配结果 
         i = p;
      }else if(i==p){
         t++;
      }else{
          i = p + next[i-p-1];
      }    
   }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值