KMP算法总结

KMP算法:就是按自左向右的方向进行匹配,在匹配过程中,当模式串P不匹配时,应尽量向右移动最大距离,以避免重复比较。

假设目标串T=t0,t1,t2,,,,,,tn模式串P=p0,p1,......pm,在模式串匹配的过程中出现了不匹配位ti!=pj,如果下一步比较的是ti和pk,需要满足什么条件呢,

一方面有:ti-k,ti-k+1,,,,ti-1=pj-k,pj-k+1,,,,,pj-1;

另一方面:ti-k,ti-k+1,,,,ti-1=p0,p1,,,,,pk-1

因此:pj-k,pj-k+1,,,,,pj-1=p0,p1,,,,,pk-1;

下面就引入部分匹配串的概念:

首先对模式串p进行与预处理,对于p在j位置找出所有的 前缀合后缀,其中最大的一对相等的p[0..........j]的前缀和p[1,,,,,,,j]的后缀为部分匹配串。

怎样求模式串每个位置上的部分匹配串长度呢,下面引入next函数,next'[j]的值表示了模式串p在j位置的部分匹配串长度。

下面给出next函数的算法:

void next(char *p,int next[])
{    int m=strlen(p);//模式串p的长度。
     next[0]=0;//位置0处的部分匹配串长度为0
     int i=1,j=0;//初始化比较位置
     while(i<m)
     { if(p[j]==p[i])//已经匹配了j+1个字符,
        {  next[i]=j+1;//部分匹配串长度加1.
             i++;j++;//比较的各个位置加1.
        }
        else{ if(j>0) j=next[j-1];//移动,用部分匹配串对齐。
              else     next[i++]=0;//j在串头部分匹配长度为0.
             }
     }
     }
匹配算法:

int KMP_match(char *T,char *p)
{   int n=strlen(T);
    int m=strlen(p);
    int i=0,j=0;
    next(P); // 预处理函数。 
    while(i<n)
    {  if(T[i]==p[j])// 已经匹配j+1个字符, 
      {  if(j==m-1) return i-j; //匹配成功返回匹配位置。 
        j++;i++;             //比较下一个位置。 
        }
        else  { if(j>0) j=next[j-1]   //失配,移动到部分匹配串。 
                else  i++;           // 失配。匹配串的首字符移动到目标串的当前位置 
              }
              }
              return -1;
    }

http://www.cnblogs.com/kwklover/archive/2007/08/18/834853.html

你可能感兴趣的:(算法,IM)