KMP 简单讲解

一种O(n+m)复杂度的字符串匹配算法,复杂度是很优秀的。
我们来看看kmp算法具体思路:就是不移动回移主串p的位置,进行匹配,只移动模式串t的位置。首先我们知道如果p[j] == t[k],那么就 j++ , k++; 如果p[j] != t[k];按照kmp的思路就是回退k的位置,j不移动,那么怎么回退成了这个算法的关键。
定义next[j] = k,代表含义t[0 – k-1] == t[j-1 – j-k+1]匹配;而且是最大长度的匹配,网上有的称作k为最大公共前缀后缀串长度,反正你理解就好,反正公式在上面已经给出,无所谓称呼。如果要暴力求解这个next[j]就是以t[0]为起点枚举长度i的前缀,和以t[j-1]为终点长度同样为i的后缀是否匹配,然后求一个最大长度,我这样只是方便理解。
高手一般不暴力,只dp;那么我们dp求解
next[j] = k ; 如果t[k] == p[j];那么next[j+1] = k + 1;
这个很好理解吧,因为t[0 – k-1] == t[j-1 – j-k+1]已经匹配了(next[j] = k);如果t[k] == t[j];那么next[j+1] = k + 1没什么问题;
关键是如果t[k] != t[j];怎么办;网上好多解释,我反正都没怎么看懂。我的解释就是:
如果我们枚举长为x,我们把最后一个端点拿出来,分别比较
t[0 – x-2] 和 t[j-1 – j-x+2] 还有 t[x] 与 t[j],你发现一个细节吗;
因为我们已知next[j] = k;意味着t[0 – k-1] 与 t[j-1 – j-k+1]已经匹配了,那么t[j-1 – j-x+2] 是不是等于 t[k-x+2 – k-1];那么就是在求一个next[k],如果t[x] == t[j],next[j+1] = next[k] + 1; 所以有k = next[k]。
最关键的讲完了。
上代码,以下是优化的next数组求解;
至于还有哪里可以优化,举个栗子:ABAB的next数组,[-1,0,0,1]
如果j == 3不匹配了,它会跳到 j ==1;然而这也肯定不匹配,因为t[j] == t[next[j]];所以才有了优化。

void Getnext(int next[],String t)
{
   int j=0,k=-1;
   next[0]=-1;
   while(j<t.length-1)
   {
      if(k == -1 || t[j] == t[k])
      {
         j++;k++;
         if(t[j]==t[k])
            next[j] = next[k];
         else
            next[j] = k;
      }
      else k = next[k];
   }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值