关闭

kmp

365人阅读 评论(0) 收藏 举报

转自:http://duanple.blog.163.com/blog/static/709717672009825004092/

kmp

  首先这个匹配算法,主要思想就是要充分利用上一次的匹配结果,找到匹配失败时,模式串可以向前移动的最大距离。这个最大距离,必须要保证不会错过可能的匹配位置,因此这个最大距离实际上就是模式串当前匹配位置的next数组值。也就是max{Aj 是 Pi 的后缀 j < i},pi表示字符串A[1...i],Aj表示A[1...j]。模式串的next数组计算则是一个自匹配的过程。也是利用已有值next[1...i-1]计算next[i]的过程。我们可以看到,如果A[i] = A[next[i-1]+1] 那么next[i] = next[i-1],否则,就可以将模式串继续前移了。

  整个过程是这样的:

void next_comp(char * str){
   int next[N+1];
   int k = 0;
   next[1] = 0;
   //循环不变性,每次循环的开始,k = next[i-1]
   for(int i = 2 ; i <= N ; i++){
      //如果当前位置不匹配,或者还推进到字符串开始,则继续推进
      while(A[k+1] != A[i] && k != 0){
           k = next[k];
      }
      if(A[k+1] == A[i]) k++;
      next[i] = k;
   }
}

  复杂度分析:从上面的过程可以看出,内部循环再不断的执行k = next[k],而这个值必然是在缩小,也就是是没执行一次k至少减少1;另一方面k的初值是0,而最多++ N次,而k始终保持非负,很明显减少的不可能大于增加的那些,所以整个过程的复杂度是O(N)。

  上面是next数组的计算过程,而整个kmp的匹配过程与此类似。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:76877次
    • 积分:1348
    • 等级:
    • 排名:千里之外
    • 原创:58篇
    • 转载:9篇
    • 译文:0篇
    • 评论:13条
    文章分类
    最新评论