zoukankan      html  css  js  c++  java
  • KMP算法

    大牛的好文  http://www.cnblogs.com/tangzhengyue/p/4315393.html

     下图摘自链接大牛的博客

    1.由"next[j] == k;"这个条件,我们可以得到A1子串 == A2子串(根据next数组的定义,前后缀那个)。

    2.由"next[k] == 绿色色块所在的索引;"这个条件,我们可以得到B1子串 == B2子串。

    3.由"next[绿色色块所在的索引] == 黄色色块所在的索引;"这个条件,我们可以得到C1子串 == C2子串。

    4.由1和2(A1 == A2,B1 == B2)可以得到B1 == B2 == B3。

    5.由2和3(B1 == B2, C1 == C2)可以得到C1 == C2 == C3。

    6.B2 == B3可以得到C3 == C4 == C1 == C2

    以下本菜的理解求next[]

    2b青年的说法;先去匹配,如果失败,可能失败的前一部分长度的字符串的前缀和后缀相同,那就可以直接把前缀移到后缀那一块,省去了很多没用的时间。

    关键就是求next数组。根据递归的思想;

    next[0]=-1;

    next[j]=k;p[0...k-1]=p[j-k...j-1];

    1.如果p[j]==p[k],p[0...k]=p[j-k...j];next[j+1]=next[j]+1=k+1;

    2.如果p[j]!=p[k],由于之前的都求了next[],所以直接移到,即匹配失败的时候,k=next[k]。

    int kmp(char *s,char *p)
    {
        int i,j,len=strlen(s);
        i=0;
        j=0;
        getnext(p);
        while(i<len)
        {
            if(j==-1||s[i]==p[j])
            {
                i++;
                j++;
            }
            else 
            {
                j=next[j];
            }
            if(j==strlen(p))
            {
                return i-strlen(p);
            }
        }
        return -1;
    }//kmp匹配部分
    
    void getnext(char *p)
    {
        int k,j,len=strlen(p);
        next[0]=-1;
        j=0;
        k=-1;
        while(j<len)
        {
            if(k==-1||p[j]==p[k])
            {
                j++;
                k++;
                next[j]=k;
            }
            else k=next[k];
        }
    }//递归思想求next

    做了几题题目后理解的next的意思:

    next 数组各值的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀。例如如果next [j] = k,

    代表j 之前的字符串中有最大长度为k 的相同前缀后缀。也就是说当前字符前的k个字符是一定相同的,但是

    s[j]不一定和s[k]相同。

    next数组关于循环节几个小应用
    (1)i - next[i] 最小循环节(第一个字母开始),循环节的长度
    (2)next[i] 最大循环节中的第几位数(此时循环节可交叉)
    (3)next[i] != 0 && i % (i - next[i]) == 0,当前是循环节中的最后一位。
    (4)在(3)的前提下 i / (i - next[i]) 表示的最大周期个数,也就是在最小循环节的前提下的最大周期个数。

  • 相关阅读:
    eslint自动格式化
    焕肤功能
    Web Components
    Webpack 中的 sideEffects
    andriod 新建Activity_ Form
    那么唯美
    C# PDF添加水印
    停止触发器
    sp_sys_ERPTrigger_base
    sql语句返回主键SCOPE_IDENTITY()
  • 原文地址:https://www.cnblogs.com/sweat123/p/4712735.html
Copyright © 2011-2022 走看看