在暴力匹配中,每趟匹配失败都是模式后移一位再从头开始比较。而某趟已匹配相等的字符序列是模式的某个前缀,这种频繁的重复比较相当于模式串在不断地进行自我比较,这就是低效率的根源。
KMP算法,全称为Knuth-Morris-Pratt算法,是一种字符串匹配算法,用于在一个文本串S中查找一个模式串P的出现位置。相较于传统的暴力匹配算法,KMP算法具有更高的效率。
KMP算法的核心思想是利用已经匹配过的信息,避免不必要的回溯。它通过构建一个辅助数组next[],记录模式串中每个位置之前最长的相同前缀和后缀的长度。在进行匹配时,当出现不匹配的情况时,通过查找next数组得到一个新的起始位置,从而避免重复匹配已经比较过的部分。
通过利用next数组的信息,KMP算法将匹配时间复杂度降低至O(n+m),其中n为文本串的长度,m为模式串的长度。
KMP算法的关键是构建next数组,它用于记录模式串中每个位置之前最长的相同前缀和后缀的长度。
模式串各个子串 | 前缀 | 后缀 | 最大公共元素长度 |
---|---|---|---|
a | 空 | 空 | 0 |
ab | a | b | 0 |
aba | a,ab | a,ba | 1 |
abab | a,ab,aba | b,ab,bab | 2 |
例如模式串”abcac“与“ababcabcacbab”进行匹配
function getNextArray(pattern):
n := pattern.length
next := new Array of size n
next[0] := -1 // 初始化next数组第一个元素为-1
i := 0 // 模式串指针
j := -1 // next数组指针
while i < n - 1 do:
if j == -1 or pattern[i] == pattern[j] then:
i := i + 1
j := j + 1
next[i] := j
else:
j := next[j]
return next
根据上述伪代码,next数组的求解过程如下:
最终返回的next数组即为KMP算法所需的结果,需要注意的是,next数组中的值不包括当前位置的字符。即next[i]表示模式串中从0到i-1的子串的最长相同前缀和后缀长度。
继续接上一节子串abcac的next求解如下:
算法推演如下:
KMP算法在字符串匹配中有着广泛的应用。它能有效地解决大规模文本搜索、DNA序列匹配等问题,提高了字符串匹配的效率。对于需要频繁进行字符串匹配的应用场景,使用KMP算法能够显著减少计算时间,提升算法性能。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有