[AcWing 831] KMP字符串
点击查看代码
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
const int M = 1e6 + 10;
int ne[N];
int main()
{
int n, m;
char p[N], s[M];
cin >> n >> p + 1 >> m >> s + 1;
for (int i = 2, j = 0; i <= n; i ++) {
while (j && p[i] != p[j + 1]) j = ne[j];
if (p[i] == p[j + 1]) j ++;
ne[i] = j;
}
for (int i = 1, j = 0; i <= m; i ++) {
while (j && s[i] != p[j + 1]) j = ne[j];
if (s[i] == p[j + 1]) j ++;
if (j == n) {
cout << i - j << ' ';
j = ne[j];
}
}
return 0;
}
- ne 数组用来记录下一次 j 应当从哪个位置开始继续匹配;
- p 和 s 都从数组下标为 1 开始存放;
- 求 ne 数组的过程:当 j 不为 0 并且 p[ i ] != p[ j + 1 ] 说明 j 应当往回退,直到 j 到达 0 或者满足前缀等于后缀的位置,如果 p[ i ] == p[ j + 1 ],则 j ++,表示下一次从后面这个位置开始匹配,最后 ne[ i ] = j 用来 ne 数组的值;
- 匹配的操作和求 ne 的操作类似,当满足 j == n 时,说明匹配成功,输出位置,并让 j = ne[ j ],注意输出的时候是 i - j + 1 - 1(i - j + 1 表示 s 数组匹配成功的起始下标,- 1 是因为定义的 s 数组是从下标为 1 开始的,而题目要求的是要从 0 开始的下标);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!