1. KMP算法概述
KMP算法(Knuth-Morris-Pratt算法)是字符串匹配领域的经典算法,由Donald Knuth、Vaughan Pratt和James Morris三位计算机科学家于1977年联合发表。这个算法解决了传统暴力匹配算法在最坏情况下时间复杂度高达O(mn)的问题,通过预处理模式串构建部分匹配表(Partial Match Table),将时间复杂度优化至O(m+n)。
我第一次接触KMP算法是在处理大规模文本搜索需求时,当时使用暴力匹配算法处理GB级文本文件时,程序经常卡死。后来改用KMP算法后,性能提升了数十倍。这个经历让我深刻认识到算法选择对程序性能的决定性影响。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. KMP算法核心原理
2.1 暴力匹配的局限性
传统的暴力匹配算法(Brute-Force)采用双指针逐个比较的方式:
- 主串指针i初始为0,模式串指针j初始为0
- 比较主串[i]和模式串[j]
- 如果相等,i和j同时后移
- 如果不相等,i回溯到本轮起始位置+1,j重置为0
这种算法在最坏情况下(如主串为"aaaaaaab",模式串为"aaab")会产生大量不必要的回溯,时间复杂度为O(mn)。
2.2 部分匹配表(PMT)的构建
KMP算法的核心创新在于预处理模式串,构建部分匹配表(PMT)。PMT记录了模式串每个位置的最长公共前后缀长度:
以模式串"ababc"为例:
- 前缀:不包含最后一个字符的所有子串("a","ab","aba","abab")
- 后缀:不包含第一个字符的所有子串("b","ba","bab","babc")
计算过程:
- 子串"a":无前后缀,长度为0
- 子串"ab":前缀["a"],后缀["b"],无公共,长度为0
- 子串"aba":前缀["a","ab"],后缀["ba","a"],公共"a",长度为1
- 子串"abab":前缀["a","ab","aba"],后缀["bab","ab","b"],公共"ab",长度为2
- 子串"ababc":前缀["a","ab","aba","abab"],后缀["babc","abc","bc","c"],无公共,长度为0
最终PMT:[0,0,1,2,0]
2.3 KMP匹配流程
构建好PMT
