• KMP学习笔记


    功能

    字符串T,长度为n。

    模板串P,长度为m。在字符串T中找到匹配点i,使得从i开始T[i]=P[0], T[i+1]=P[1], . . . , T[i+m-1]=P[m-1]

    KMP算法先用O(m)的复杂度对模板串进行处理,然后O(n)进行匹配。总时间复杂度O(m+n)

    注意失配函数f[i]为第i位处不能匹配时应当转向检查第f[i]位是否匹配:

    比如模板串:

    0

    1

    2

    3

    4

    5

    6

    A

    B

    B

    A

    A

    B

    A

    得到的失配函数为:

    0

    1

    2

    3

    4

    5

    6

    7

    0

    0

    0

    0

    1

    1

    2

    1

    也即是说如果在模板串第5位失配,即当前位匹配不成功:

    字符串

    X

    X

    A

    B

    B

    A

    A

    K

    X

    模板串

    A

    B

    B

    A

    A

    失配

    那么根据失配函数f[5]=1,转移到1,表示已经匹配好一位,相当于模板串整体右移,但当前匹配的位置不变,然后继续匹配。

    字符串

    X

    X

    A

    B

    B

    A

    A

    K

    X

    模板串

    A

    失配函数另一种用途:如果P存在循环节,f[i]为前一个循环节对应字符的位置。比如ABCABC,那么P[4]=B,而f[5]=2,也就是P[1]=B。

    用途:计算字符串循环节长度。

    构造失配函数:

    s为模板串,f为待构造的失配数组,开始时为空

    void getFail(char *s,int *f)
    {
        int m=strlen(s),j;
        f[0]=0;f[1]=0;
        for (int i=1;i<m;i++)
        {
            j=f[i];
            while (j&&s[i]!=s[j]) j=f[j];
            f[i+1]=(s[i]==s[j]?j+1:0);
        }
    }

    匹配函数:

    输入

    t:文本,一大串字符串

    s:模板,待匹配的模板

    f:失配数组,一开始为空,函数过程中调用失配数组构造函数

    输出

    t字符串中模板第一次出现的位置(从0开始)

    int find(char *t,char *s,int *f)
    {
        int n=strlen(t),m=strlen(s);
        getFail(s,f);
        int j=0;
        for (int i=0;i<n;i++)
        {
            while (j&&s[j]!=t[i]) j=f[j];
            if (s[j]==t[i]) j++;
            if (j==m) return i-m+1;
        }
    }
  • 相关阅读:
    《DSP using MATLAB》Problem 6.4
    《DSP using MATLAB》Problem 6.3
    《DSP using MATLAB》Problem 6.1
    《DSP using MATLAB》Problem 5.38
    整除分块+取模
    尺取法(滑窗,双指针)
    uva247电话圈(floyd)
    uva1151并查集+最小生成树
    uva1395 苗条的生成树
    uva10562看图写树
  • 原文地址:https://www.cnblogs.com/zhyfzy/p/4290790.html
Copyright © 2020-2023  润新知