KMP算法

http://www.cnblogs.com/ziyi--caolu/archive/2013/01/01/2841548.html

写KMP的不错的博客。

KMP算法,是字符串匹配O(N)的算法,和朴素字符串匹配的区别在于:匹配失败时会跳过已知不可能匹配的位置。

朴素字符串匹配:  原串S=ababcababa,子串P=ababa。 

            ababcababa  ababcababa  ababcababa    ababcababa

            ababa      ababa       ababa       ababa

            可以看到:子串P中有ab 重复,一旦匹配失败,子串不必只移动一位,而是移动到下一个 需要匹配的位置

KMP算法引入了next数组,表示匹配失败后 应该匹配子串的哪个位置,通过对子串的预处理得到next数组。

这个思想也被用在了其他算法中,比如AC自动机- - 我是懵逼的

next[i]=k表示  P[0~k-1] ==P[i-k~i-1]  这两段字符串相同!

  next数组的定义:

  1:j==0  next[0]=-1;

  2: next[j]=max  k(k<j)&&P[0 ~ k-1]==P[j-k ~ j-1];

  3:其他情况 next[j]=0;

例如:

P      a    b   a    b   a

j       0   1    2   3   4

next -1  0    0   1   2

KMP的过程:if(不匹配)

        if(next[j]==-1) i后移,j置0;

        else {j=next[j];i不变;}

i  指向原串S的匹配位置,j  指向子串P的匹配位置.

求next数组的过程:根据定义来求。

  next[0]=-1;

  if(P[j]==P[k])  next[j+1]=next[j]+1   (k=next[j])

  else  当前指针指向下一个需要匹配的位置  ,即k=next[k]

   不允许出现next[j]=-1

FIND NEXT:

void getnxt()
{
    nxt[0]=-1;
    int i=0,j=-1;
    while(i<m)
    {
        if(j==-1||b[i]==b[j]) {
            i++;j++;
            nxt[i]=j;
        }
        else j=nxt[j];
    }
}

  KMP:

int kmp()
{
    getnxt();
    int i=0,j=0;
    while(i<n)
    {
        if(a[i]==b[j]||j==-1)
        {
            i++;j++;
        }
        else j=nxt[j];
        if(j==m)return i;
    }
    return -1;
}

  

落霞与孤鹜齐飞,秋水共长天一色
原文地址:https://www.cnblogs.com/star-and-me/p/6805771.html