zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

    落霞与孤鹜齐飞,秋水共长天一色
  • 相关阅读:
    php -- php数组相关函数
    php -- 数组排序
    php -- in_array函数
    php -- 魔术方法 之 删除属性:__unset()
    无符号整型与有符号整型相运算规则
    N个节点的二叉树有多少种形态
    getopt_long
    typedef
    约瑟夫环问题算法(M)
    C语言基础
  • 原文地址:https://www.cnblogs.com/star-and-me/p/6805771.html
Copyright © 2011-2022 走看看