当前位置 博文首页 > 明圣的博客:kmp算法——next数组——前缀表

    明圣的博客:kmp算法——next数组——前缀表

    作者:[db:作者] 时间:2021-08-07 15:37

    kmp算法对于刚接触算法的朋友来说是真的一点也不友好,我也同样遭遇了它的毒打,翻阅了很多资料,终于把它弄明白了, 其中最难得就是next数组了,于是做一个next数组的总结。

    话不多说,下面请观看我的表演,请戴好你的墨镜。
    在这里插入图片描述

    1、next数组是什么,这个可是kmp算法的精华,只要学会这个,其他的都是洒洒水啦。当然,这个也是最烧脑的一点。

    next数组其实就是构造的前缀表,先说说这个前缀表的由来。
    前缀表可以暂时理解为:字符串最长公共前缀后缀长度。这么长一串东西,请问你刚看见有什么感受。
    在这里插入图片描述
    没错,就是难搞。好吧,我肯定不能也让你难搞。
    下面开始说人话
    先了解两个概念:“前缀"和"后缀”。 "前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。

    下面以”ABCDABD”为例,进行介绍:
    ”A”的前缀和后缀都为空集,共有元素的长度为0;
    ”AB”的前缀为[A],后缀为[B],共有元素的长度为0;
    ”ABC”的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;
    ”ABCD”的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;
    ”ABCDA”的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为”A”,长度为1;
    ”ABCDAB”的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为”AB”,长度为2;
    ”ABCDABD”的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。

    现在应该知道什么是字符串最长公共前缀后缀长度了吧。

    接下里最重要也是最烧脑的部分来了。
    接下里最重要也是最烧脑的部分来了。
    接下里最重要也是最烧脑的部分来了。
    在这里插入图片描述
    现在需要构造前缀表了,也就是建立next数组。

    分为三步:
    1、初始化
    2、前后缀的末尾不相同时怎么处理(有的文章直接就写个前后缀,让你看的一头雾水)
    3、前后缀的末尾相同时怎么处理
    >可能第2、3步你现在不是很理解,没事,多看下面几遍的例子

    接下里看看如何实现这几步(遇见不明白的先看完例子再回来思考)

    1、初始化(python代码)

    #初始化一个长度为a的空数组,这个长度就是要匹配的模式串长度
    next=[’’ for i in range(a)]
    k=-1
    next[0]=k

    2、前后缀的末尾不相同时处理办法

    while (k>-1 and needle[k+1]!=needle[i]):
    	k=next[k]
    

    3、前后缀的末尾相同时的处理办法

    if needle[k+1]==needle[i]:
        k+=1
    next[i]=k
    

    完整代码

    def getnext(self,a,needle):
            next=['' for i in range(a)]
            k=-1
            next[0]=k
            for i in range(1,len(needle)):
                while (k>-1 and needle[k+1]!=needle[i]):
                    k=next[k]
                if needle[k+1]==needle[i]:
                    k+=1
                next[i]=k
            return next
    

    参考文章:ACM
    代码随想录

    cs
    下一篇:没有了