KMP字符串匹配算法
$KMP$算法浅析
算法介绍
- 该算法是由$D.E.Knuth$、$J.H.Morris$、$V.R.Pratt$三位神犇提出的,因此人们称它为克努特-莫里斯-普拉特操作,简称$KMP$算法
- 该算法是一种字符串匹配算法,用于寻找模式串在文本串中出现的位置(下标)、次数 等,相较于传统的暴力解法,复杂度由$O(nm)$减小到了$O(n+m)$,是速度极快的一种字符串匹配算法
算法思想&流程
举个例子
1 |
|
如果使用暴力解法,在模式串指针指向c
时,发现文本串不匹配,于是模式串指针要退回到初始位置,而文本串指针只前进一步,形成这样一个局面
1 |
|
而接下来一次匹配完全是不可能匹配出答案的(无用的匹配),我们可以发现,完全可以在前一步结束后,让文本串的指针前进两步,成为下面这个形式
1 |
|
换句话说,就是让模式串的指针退回两步,将模式串分割成为两个具有相同前缀的子串
1 |
|
这里就是出现了两个一模一样的ab
子串,那么接下来就可以从前一个具有相同前缀的子串末尾开始继续匹配了
那么问题来了,这样一个操作具体如何实施呢?
这里定义文本串数组为a
,模式串数组为b
我们定义一个数组kmp[j]
(很多地方next,老子就不用):表示当匹配到b
的第j
个字母而第j+1
个字母无法匹配的时候,新的j
最大值是多少
这也就是我们每次无法匹配时需要做的回退操作的核心数组,其中kmp[j]
应该是所有满足b[1...kmp[j]]==b[j-kmp[j]+1...j]
的最大值
我们需要明确的一点是:kmp数组只和模式串本身有关,我们在做kmp算法时,是先利用模式串数组来预处理好kmp数组,再利用这个处理好的kmp数组去匹配文本串数组
而这个预处理的过程,就是模式串自己匹配自己的过程(我搞我自己)
因此kmp算法的大致框架就是两次匹配:一次用模式串来构造kmp数组,另一次用kmp数组来匹配文本串
而具体的实行方法,还是看代码吧(原谅我蒻我讲不清楚)
PS:一开始会觉得这个算法很神奇,而且想不明白(反正蒟蒻本蒻是想了一个多小时才想明白)
算法代码
代码加了一点输出内容,见题目链接:洛谷 P3375 [模板]KMP字符串匹配
1 |
|
- 太神奇了,这么美的算法居然这么早就有人提出来来了,也太强了叭Orz
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!