要想彻底理解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个字符开始匹配,从而省去了前两个的匹配时间