KMP算法,又称作“看猫片”算法(误),是一种改进的字符串模式匹配算法,可以在O(n+m)的时间复杂度以内完成字符串的匹配操作,其核心思想在于:当一趟匹配过程中出现字符不匹配时,不需要回溯主串的指针,而是利用已经得到的“部分匹配”,将模式串尽可能多地向右“滑动”一段距离,然后继续比较。
![KMP(看猫片)算法](https://images2018.cnblogs.com/blog/1485189/201809/1485189-20180909160802638-149491311.jpg)KMP(看猫片)算法
![]()
1. 朴素的字符串模式匹配算法
求一个字符串(模式串)在另一个字符串(主串)中的位置,称为字符串模式匹配。
在朴素的字符串模式匹配算法中,我们对主串S和模式串T分别设置指针i和j,假设字符串下标从0开始,初始时i和j分别指向每个串的第0个位置。在第n趟匹配开始时,i指向主串S中的第n-1个位置,j指向模式串T的第0个位置,然后逐个向后比较。若T中的每一个字符都与S中的字符相等,则称匹配成功,否则,当遇到某个字符不相等时,i重新指向S的第n个位置,j重新指向T的第0个位置,继续进行第n+1趟匹配。
例如,我们对模式串T=“abaabcac”和主串S=“abcabaabaabcacb”进行匹配。如图1.1,此时正在进行第4趟匹配,S[3...7]与T[0...4]均相等,但当i=8,j=5时,S[8]与T[5]不相等,匹配失败。于是,置i=4,j=0,相当于将模式串向右移动一位后,重新开始下一趟匹配,如图1.2。
![图1.1](https://images2018.cnblogs.com/blog/1485189/201809/1485189-20180909160938585-1146094368.png)
图1.1 当i=8,j=5时,字符不相等,匹配失败
![图1.2](https://images2018.cnblogs.com/blog/1485189/201809/1485189-20180909161818355-942371414.png)
图1.2 将模式串向右移动一位后,重新开始下一趟匹配
利用此种方法进行字符串匹配,最坏情况下时间复杂度为O(n*m),其中n和m分别为主串和模式串的长度。
2. 改进的字符串模式匹配算法——KMP算法
在上面的例子中,我们可以看到,当i=8,j=5时,S[8]与T[5]不相等,于是置i=4,j=0,相当于将模式串向右移动一位,再开始下一趟匹配。然而,通过观察我们可以发现,之后的两趟匹配,即i=4,j=0以及i=5,j=0都是不必要的。这是因为,在之前的一趟匹配过程中,我们已经部分匹配了T的子串“abaab”。此时将T向右移动一位,则相当于对T中的“abaab……”与S中的“baab……”进行匹配,显然无法匹配成功。继续右移T,则相当于对T中的“abaab……”与S中的“aab……”进行匹配,依然无法匹配成功。只有当T向右移动3位后,此时对T中的“abaab……”与S中的“ab……”进行匹配,才会有成功的可能,也就有必要向后继续进行比较。如图2.1。
![图2.1](http