KMP算法—串的模式匹配算法

KMP算法是一种改进的字符串匹配算法,KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)

KSP算法的匹配过程:
在这里插入图片描述

KMP算法是怎样减少模式串与主串的匹配次数呢???

每当匹配过程出现字符比较不等

  • 主串的i 指针不动
  • 模式串的 j 指针定位到某个数

上面提到的模式串中 j 指针定位到某个数其实就是next值

若令 next[j]=k,则next[j] 表明当模式中第 j 个字符与主串中相应字符“失配”时,在模式中需要重新和主串中该字符进行比较的字符的位置


我们规定任何一个串,next[1]=0,举个例子求next:

已知模式串为ABABABB(如下图),在 j =5时,模式串与主串对应字符不匹配,那么求next值就需要找 j 前面的 j-1(即为4) 个字符。j 要移动的下一个位置需要满足这样的性质:最前面的k(即为2)个字符和 j 之前的最后k(即为2)个字符是一样的,且 k 必须是最大的情况。

此时FL=“AB”=FR,想要知道下一次的 j 指针对应的值只需要将 FL 与 FR 相重合(通过移动重合)即可 ,重合后此时 j 指向的值为第三个字符(A),说明next值为3。
在这里插入图片描述
用公式验证一下,next=FL串长+1=FR串长+1=3
在这里插入图片描述

通过上面的例子再来理解一下模式串next函数的定义

在这里插入图片描述
next[j] = 0的意思是主串的第 i 个字符与模式的第一个字符不等,应从主串的第 i+1 个字符起重新进行匹配


由此上面的定义我们可以推出模式串的next函数值,举个例子:
在这里插入图片描述
如果按照上面的next值进行匹配,就是下面的匹配过程:
在这里插入图片描述


KSP算法如下:

int Index_KMP(SString S,SString T,int pos)
{
   i=pos;j=1;
   while(i<=S.length && j<=T.length)    //两个串均未比较到串尾
   {
      if(j==0 || S.ch[i]==T.ch[j])
        {++i;++j;}                      //继续比较后续字符
      else
        j=next[j];                      //模式串向右移动
    }
   if(j>T.length)  return i-T.length;   //匹配成功
   else  return 0;                      //匹配失败
}

计算next函数值(O(m))算法如下:

void get_next(SString T,int next[])
{
   i=1;next[1]=0;j=0;
   while(i<T.length)
   {
       if(j==0 || T.ch[i]==T.ch[j])
         {++i;++j;next[i]=j;}
       else
         j=next[j];
   }
}           

我们前面定义的next函数在某些情况下尚有缺陷。
例如模式”aaaab“在和主串”aaabaaaab“匹配时,当 i =4、j =4 时S.ch[4] ≠ T.ch[4],由 next[j]的指示还需要进行i=4、j=3,i=4、j=2,i=4、j=1这3次比较。实际上,因为模式中1~3个字符和第4个字符都相等,因此不需要再和主串的第4个字符相比,可以将模式连续向右滑动4个字符的位置直接进行i=5、j=1的字符比较。直接将next[3]、next[2]、next[1]改为0即可。nextval[j] 即为修正后的next值
在这里插入图片描述

计算next函数修正值算法如下:

void get_nextval(SString T,int nextval[])
{
   i=1;nextval[1]=0;j=0;
   while(i<T.length)
   {
      if(j==0 || T.ch[i]==T.ch[j])
      {
         ++i;++j;
         if(T.ch[i]!=T.ch[j]) 
           nextval[i]=j;
         else
           nextval[i]=nextval[j];
      }
      else  j=nextval[j];
   }
}               

这个是关于BF算法的讲解BF算法—串的模式匹配算法
借鉴:《数据结构》 严蔚敏

发布了15 篇原创文章 · 获赞 43 · 访问量 4469

猜你喜欢

转载自blog.csdn.net/wmy0217_/article/details/104053548
今日推荐