KMP 算法 自己的一些理解

时间:2022-12-11 18:51:07

 

KMP算法是一种高效的字符串匹配算法,比较难以理解,下面只是我的一点个人理解,以后有更深入的理解会陆续加进去的。

1.     比较简单的一种字符串匹配算法

String S; String T

S是待匹配串,T是匹配串,又称模式串。所以字符串匹配又称模式匹配。

S:

A

B

A

B

C

A

B

C

A

C

B

A

B

C

B

A

B

C

A

C

 

T:

简单的方法,一个循环即可,但是时间复杂度确实o(n*n)

 

看着是一个循环,但是由于可能存在的不断的回溯,导致时间复杂度的提高。

2.     KMP的出现就是为了解决这种回溯问题,使得时间复杂度成为线性复杂度,o(n+m).

KMP的思想就是不要回溯i指针,必要的时候移动模式串j指针的位置。

一:

S:

A

B

A

B

C

A

B

C

A

C

B

A

B

C

B

A

B

C

A

C

 

 

 

 

T:

二:

注意,CA不匹配的时候,如果是一般匹配算法,那么i要回溯到第一个B的位置,即:

S:

A

B

A

B

C

A

B

C

A

C

B

A

B

C

B

 

A

B

C

A

C

 

 

 

 

T:

就像是这样的。

但是注意到,BA肯定是不匹配的,所以拉回两个更加合适,KMP算法大概就是这个意思,省略去已经比较过的不用再比较子串。

那么KMP算法最重要的问题就是如何寻找当串不匹配时,j应该拉回到那个位置比较合适。在此有个公式:

KMP 算法 自己的一些理解

由此定义可以推断出下面T字符串的next[j]的值:

J

1

2

3

4

5

6

7

8

模式串

A

B

A

A

B

C

A

C

Next[j]

0

1

1

2

2

3

1

2

有了这个理念,再求匹配就方便了,程序如下:

 

下面问题是:如何求next[j]

你可能会说,不是有公式了吗?直接用公式求不就行了吗?

但是公式中的求法无法直接搬到程序中,很不方便,下面的方法使得寻找next[j]时间复杂度为o(m)

由定义可知:

Next[1]=0;

设:next[j]=k,那么存在下列等式:

KMP 算法 自己的一些理解

此时next[j+1]=

1) KMP 算法 自己的一些理解,说明模式串中存在等式 :

KMP 算法 自己的一些理解

并且不可能再存在比这个K更大的K存在,符合next[j]公式的定义。那么next[j+1]=next[j]+1;

2) 如果KMP 算法 自己的一些理解 ,那么剩下的问题是一个新的模式匹配问题,整个模式串既是主串又是模式串,在匹配的过程中,由于

KMP 算法 自己的一些理解

是成立的,则此时应将模式向右滑动至第next[k]个字符串和主串中的第j个字符相比较。这个过程是迭代过程,即有:next[j+1]=next[k]+1

如果一直不满足匹配状态,那么next[j+1]=1

   综上所述,可得算法: