扩展 KMP/exKMP(Z 函数)学习笔记
声明
本文章转载自 shangruolin 的博客,已经过作者(存疑)同意,帮TA宣传一下。
扩展 KMP/exKMP(Z 函数)学习笔记兼 P10479 匹配统计 题解。
LCP:最长公共前缀。
Z 函数,又称扩展 KMP(exKMP),能够在
定义
那么求解
假设现在已经求出了
定义
那么如果
接着,我们尝试进行暴力匹配,如果
暴力匹配完后更新
Z 函数的复杂度是
求解
z[1] = m; // 完全匹配
for (int i = 2, l = 0, r = 0; i <= m; i++) {
if (i <= r) z[i] = min (z[i - l + 1], r - i + 1); // 获取初值
while (i + z[i] <= m && b[i + z[i]] == b[z[i] + 1]) z[i] ++; // 暴力匹配
if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1; // 更新 l, r
}
同样,我们定义
则类似的,可以得到求解
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 && a[i + p[i]] == b[p[i] + 1]) p[i] ++;
if (i + p[i] - 1 > r) l = i, r = i + p[i] - 1;
cnt[p[i]] ++; // 统计答案
}
对于每个询问,若询问长度为
完整代码:
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 && a[i + p[i]] == b[p[i] + 1]) p[i] ++;
if (i + p[i] - 1 > r) l = i, r = i + p[i] - 1;
cnt[p[i]] ++; // 统计答案
}
本文没有图解,对初学者来说可能比较抽象。想要更好理解 Z 函数的同学可以前往 P5410 【模板】扩展 KMP/exKMP(Z 函数) 的题解区学习。
大家有任何建议或疑惑都可以在评论中提出,感谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效