@Dounm
2017-04-09T11:09:14.000000Z
字数 1383
阅读 2618
Blog
(称被匹配串为str
,匹配串为pat
)
朴素的字符串匹配算法就是每次将pat
后移一位,然后继续从pat
的第一位开始比较。
但其实我们已经获取了信息『不匹配位置的前面的字符都是匹配的』.
朴素做法并没有利用到这个信息,而KMP就是要利用这个信息加快速度。
pat
必然是要后退,关键在于后退几位。pat
的前7位是『ABCADAB』,pat
是『ABCADABxxx』str
在当前匹配位置的7位子串是『ABCADAB』,str
是『xxxABCADABxxx..xx』pat
后退的过程中: str
在当前匹配位置是『BCADABxxxx』,pat
是『ABCADABxxx』,第一位就不匹配str
是『CADABxxxxx』,pat
是『ABCADABxxx』,第一位就不匹配str
是『ADABxxxxxx』,pat
是『ABCADABxxx』,第一位匹配,第二位不匹配str
是『DABxxxxxxx』,pat
是『ABCADABxxx』,第一位就不匹配str
是『ABxxxxxxxx』,pat
是『ABCADABxxx』,第一位和第二位都匹配,后面是否匹配无法根据现有信息得到,需要进一步获得str
后续的子串是什么。str
是『ABxxxxxxxx』,开头的两个字符是『ABCADAB』的后两位后缀『AB』。而pat
是『ABCADABxxx』,前两位前缀正好是『AB』。str
的开头都是匹配的子串『ABCADAB』的后缀;pat
都是『ABCADAB』的前缀。<前缀,后缀>
对,找到相等且最长的前后缀对即可。<前缀=AB,后缀=AB>
,长度为2。而『ABCADAB』长度为7,因此我们可以直接后退7-2=5步即可。pat
的前缀,而且pat
的每一个前缀都有可能是匹配的子串。所以我们只需提前对pat
子串进行一次处理即刻,记录下pat
的每个前缀作为匹配的子串时,相等且最长的前后缀对的长度即可。(即代码里的next
数组)附上我用Python
实现的KMP算法的代码:Dounm/Fun-Programs/string-matching/kmp.py