扩展KMP学习笔记
前置芝士: KMP, manachar
告示:本文字符串下标均从 开始。
扩展KMP算法提供了一个计算 函数的方法。
求解 函数
定义 函数 表示字符串 以下标 为开头的后缀与 的最长公共前缀。
根据定义, , 为 的长度。
如果直接暴力求解,显然每计算一次 都要花费 的时间,总时间是 。
不过可以通过扩展KMP算法,将此优化到 。
假设我们计算 时, 的 已经全部算出。
我们可以维护一个 最大的能与 前缀匹配的。(这句话好好理解)
对于 直接将 初始成 , 否则为 。
然后暴力往后匹配,求出 , 更新之前的 。
因为匹配次数跟 相同, 所以是 的。
CODE

inline void getZ(char *s, int n) { for (int i = 1; i <= n; ++ i) z[i] = 0; z[1] = n; for (int i = 2, l = 0, r = 0; i <= n; ++ i) { if (i <= r) z[i] = min(z[i-l+1], r-i+1); while (i + z[i] <= n && s[i+z[i]] == s[z[i]+1]) ++ z[i]; if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1; } }
求解文本串的后缀与模式串的匹配
根据上文, 我们可以先求出模式串的 函数。
接着类似于 KMP, 我们对文本串开始对模式串进行匹配,发现计算方式与 函数类似,于是只要改一下就行了。
CODE

inline void exkmp(char *s, int n, char *t, int m) { getZ(t, m); for (int i = 1; i <= n; ++ i) p[i] = 0; for (int i = 1, l = 0, r = 0; i <= n; ++ i) { if (i <= r) p[i] = min(z[i-l+1], r-i+1); while (i + p[i] <= n && s[i+p[i]] == t[p[i]+1]) ++ p[i]; if (i + p[i] - 1 > r) l = i, r = i + p[i] - 1; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具