扩展 KMP(Z 函数)
扩展 KMP(Z 函数)
下文用 表示 , 表示当前 最右的匹配段。
问题一
要解决的问题为:求出 函数,,其中 表示 的最长相同前缀。
考虑到 所以 有 。
因此,求 可以利用到 ,即 。
分类讨论:
-
- 若 则 ;
- 若 则令 然后往后扩展。
- 则令 然后向后扩展。
由此可以写出代码:
nS = strlen(s + 1);
l = 0, r = 0;
for (int i = 2; i <= nS; ++ i)
{
if (i <= r && z[i - l + 1] < r - i + 1)
z[i] = z[i - l + 1];
else
{
z[i] = std::max(r - i + 1, 0);
while (i + z[i] <= nS && s[1 + z[i]] == s[i + z[i]])
z[i] ++;
}
if (i + z[i] - 1 > r)
l = i, r = i + z[i] - 1;
}
显然,外层循环只会循环 次,而内层 while 循环每循环一次必使得 增大, 顶多增大到 ,故内层循环顶多进行 次。
综上所述,时间复杂度为 。
问题二
我们要解决的问题为:求 与 每一个后缀的 。
把 拼起来做就可以了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧