KMP算法

来源:互联网 发布:梦龙即时通讯软件 编辑:程序博客网 时间:2024/06/07 23:18

网上有很多的KMP算法,写得也很好。

KMP的核心就是next数组的求法和含义。

只要搞懂了next数组, 那理解KMP就只是分分钟的事情。

附上B站的一个外国大佬讲的KMP,很好理解。

看一遍不懂再看第二遍,讲的很好。

点这里


KMP常用来求主串的子串中是否出现了模式串,或者出现了几次,或者出现的首位置。


其实关于next的应用还有很多,下面说下用next数组求循环节。(首先需要完全彻底理解next数组)

假设主串str的长度为len,且str存在最小循环节,循环节的长度L为len-next[len],子串为str[0…L-1]。

(1)如果len可以被len - next[len]整除,则表明字符串S可以完全由循环节循环组成,循环周期T=len/L。

(2)如果不能,说明还需要再添加几个字母才能补全。需要补的个数是循环个数L-len%L 。

借鉴网上的一个next数组的例子

对于主串abcdabc

如:abcdabc

index

0

1

2

3

4

5

6

7

char

a

b

c

d

a

b

C

 

next

-1

0

0

0

0

1

2

3

 

如对于a,ab,abc,abcd,很明显,前缀和后缀相同的长度为0

  对于长度为5的子串abcda,前缀的a和后缀的a相同,长度为1

  对于长度为6的子串abcdab,前缀的ab和后缀的ab相同,长度为2


现在举几个循环节的例子(假设主串能够成循环节的情况下)

1.无重叠

主串: abcabc(最后的c的下标为5)

next[ 6 ] = 3;  且 len = 6,  L = len - next[ 6 ] , len能整除L, 所以主串的循环节为3..

2.重叠

主串:abababab

next[ 8 ] = 6;  L = len - next[ len ] = 2; len % L == 0; 所以主串的循环节为2.

3.差元素

主串abcdabc

next[ 7 ] = 3; L = len - next[ len ] = 4; len % L != 0; 所以需要添加几个元素;  需要添加的个数为 add = L - len % L = 1。




0 0
原创粉丝点击