KMP字符匹配算法原理

441 阅读2分钟

简介:
KMP算法是一种改进的字符匹配算法。由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。 它的核心思想是,通过一个next[]数组,在匹配失败后,减少字符移动的距离,达到快速匹配的目的。


要想彻底理解KMP算法,必须要知道几个核心概念: 最长相同前后缀:即从前往后找,从后往前找,相同前后缀中最长的字符串。 Next[]数组存放的是子字符串最长前后缀的长度。

比如 ABCDABD 的next[]数组

子字符串

前缀

后缀

最长相同前后缀

最长相同前后缀长度

next[1]

A


Null

0

Next[2]

AB

A

B

Null

0

Next[3]

ABC

A,AB

C,BC

null

0

Next[4]

ABCD

A,AB,ABC

D,CD,BCD

null

0

Next[5]

ABCDA

A,AB,ABC,ABCD

A,DA,CDA,BCDA

A

1

Next[6]

ABCDAB

A,AB,ABC,ABCD,ABCDA

B,AB,DAB,CDAB,BCDAB

AB

2

Next[7]

ABCDABD

A,AB,ABC,ABCD,

ABCDA,ABCDAB

D,BD,ABD,DABD,

CDABD,BCDABD

null

0


关于next[]的作用,举个栗子:

假如有字符串α= ****AB****ABC***,要查找的字符串为β= AB****ABD***

当匹配到这种情况时=> α: ****AB****ABC*** 

                                     β:       AB****ABD***

β的第9个字符与α的第13个字符不匹配,那么就要移动β字符。

由题设可知β的前8个字符中,1~2之间的字符(AB)=7~8之间的字符(AB)是相同的,即next[8]=2。

α的第5~12之间的字符(AB****AB)和β的1~8之间的字符(AB****AB)是匹配的,匹配的长度是8。

由此可知,α的11~12之间的字符(AB)与β的7~8之间的字符(AB)是相等的

=> α的11~12之间的字符(AB)=β的1~2之间的字符(AB)

所以我们只要将β字符串向前移动的长度=已匹配的长度8 -next[8](β1~8之间字符最长的相

同前后缀(AB)长度)=6;即只要将β向前移动6位

                                α: ****AB****ABC***

                                β:                  AB ****ABD***


从β的第3个字符开始匹配,从而省去了前两个的匹配时间