码迷,mamicode.com
首页 > 其他好文 > 详细

KMP算法

时间:2014-09-10 23:40:31      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:blog   ar   strong   div   问题   sp   log   on   c   

KMP算法中,如果当前字符匹配成功,即S[i]==T[j],令i++,j++,继续匹配下一个字符;如果匹配失败,即S[i] != T[j],需要保持i不变,并且让j = next[j],这里next[j] <=j -1,即模式串T相对于原始串S向右移动了至少1位(移动的实际位数j - next[j]  >=1

 

当匹配到S[i] != P[j]的时候有 S[i-j…i-1] = P[0…j-1]. 如果下面用j_next去匹配,则有P[0…j_next-1] = S[i-j_next…i-1] = P[j-j_next…j-1]

 

 

next[j]=k>0时,表示P[0...k-1]=P[j-k,j-1]。同时当P数组的第J个元素与S对应的元素不匹配,让P里面的第NEXT[J]与这个S元素尝试匹配

因此KMP算法的思想就是:在匹配过程称,若发生不匹配的情况,如果next[j]>=0,则目标串的指针i不变,将模式串的指针j移动到next[j]的位置继续进行匹配;若next[j]=-1,则将i右移1位,并将j置0,继续进行比较。

 

 

那么这个next数组如何得到,这个NEXT只与P数组有关,与S无关。

按照递推的思想:

   根据定义next[0]=-1,假设next[j]=k, 即P[0...k-1]==P[j-k,j-1]

   1)若P[j]==P[k],则有P[0..k]==P[j-k,j],很显然,next[j+1]=next[j]+1=k+1;

   2)若P[j]!=P[k],则可以把其看做另一个模式匹配的问题,即匹配失败的时候,k值如何移动才能使得P[...K‘]=P[...J],显然K‘=next[k]。

void getNext(char *p,int *next)
{
    int j,k;
    next[0]=-1;
    j=0;
    k=-1;
    while(j<strlen(p)-1)
    {
        if(k==-1||p[j]==p[k])    
//匹配的情况下,p[j]==p[k];j等于0、k等于-1的时候表示第1(J++后等于1)个元素不匹配,只能尝试第0个元素,由于前面没有别的元素,假定前面所有元素全部相等 { j++; k++; next[j]=k;//当J匹配不成功时候的备用元素 } else //p[j]!=p[k] k=next[k]; } }

  KMP本身算法:

int KMPMatch(char *s,char *p)
{
    int next[100];
    int i,j;
    i=0;
    j=0;
    getNext(p,next);
    while(i<strlen(s))
    {
        if(j==-1||s[i]==p[j])
        {
            i++;
            j++;
        }
        else
        {
            j=next[j];       //消除了指针i的回溯
        }
        if(j==strlen(p))
            return i-strlen(p);
    }
    return -1;
}

  

   

KMP算法

标签:blog   ar   strong   div   问题   sp   log   on   c   

原文地址:http://www.cnblogs.com/notlate/p/3965427.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!