[AcWing 831] KMP字符串

image
image


点击查看代码
#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;
}

  1. ne 数组用来记录下一次 j 应当从哪个位置开始继续匹配;
  2. p 和 s 都从数组下标为 1 开始存放;
  3. 求 ne 数组的过程:当 j 不为 0 并且 p[ i ] != p[ j + 1 ] 说明 j 应当往回退,直到 j 到达 0 或者满足前缀等于后缀的位置,如果 p[ i ] == p[ j + 1 ],则 j ++,表示下一次从后面这个位置开始匹配,最后 ne[ i ] = j 用来 ne 数组的值;
  4. 匹配的操作和求 ne 的操作类似,当满足 j == n 时,说明匹配成功,输出位置,并让 j = ne[ j ],注意输出的时候是 i - j + 1 - 1(i - j + 1 表示 s 数组匹配成功的起始下标,- 1 是因为定义的 s 数组是从下标为 1 开始的,而题目要求的是要从 0 开始的下标);
posted @   wKingYu  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
欢迎阅读『[AcWing 831] KMP字符串』
点击右上角即可分享
微信分享提示