kmp算法——next数组——前缀表

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

话不多说,下面请观看我的表演,请戴好你的墨镜。
kmp算法——next数组——前缀表

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

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。

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

接下里最重要也是最烧脑的部分来了。
接下里最重要也是最烧脑的部分来了。
接下里最重要也是最烧脑的部分来了。
kmp算法——next数组——前缀表
现在需要构造前缀表了,也就是建立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
代码随想录

上一篇:数据结构笔记学习


下一篇:KMP解释+原理