AcWing 831.KMP字符串

本文介绍了如何使用Knuth-Morris-Pratt(KMP)算法在C++中解决字符串匹配问题,即在给定字符串S中找出模式串P的所有出现位置。通过构建next数组,算法有效地避免了无效的字符比较,提高了搜索效率。
摘要由CSDN通过智能技术生成

AcWing 831.KMP字符串

#include <iostream>

using namespace std;

const int N = 100010, M = 1000010;
// 题意:模式串 P在字符串 S中多次作为子串出现。
// 求出模式串 P在字符串 S中所有出现的位置的起始下标。
int n, m;
int ne[N];
char s[M], p[N];

int main()
{
    // p+1和s+1的目的是 使得字符串从1开始,避免0.
    cin >> n >> p + 1 >> m >> s + 1;

    // 求next数组。在p字符串本身内,找到最长的前后缀,方便ne的指向。
    for (int i = 2, j = 0; i <= n; i++)
    {
        while (j && p[i] != p[j + 1])
            j = ne[j];
        // 如果前后缀相同,此时j++,也就是前后缀长度++
        if (p[i] == p[j + 1])
            j++;
        // 把这次求出的前后缀长度记入ne数组。
        ne[i] = j;
    }
    // kmp算法过程
    for (int i = 1, j = 0; i <= m; i++)
    {
        // 在j可以向后退的前提下,并且s和p的这一位不匹配,j向前退。
        while (j && s[i] != p[j + 1])
            j = ne[j];
        // 如果s和p的这一位匹配成功,那么继续检查下一位。
        if (s[i] == p[j + 1])
            j++;
        // 如果匹配完成,在字符串S中找到了P这一子字符串,输出起始位置。
        // 并且将j向后退,继续检查字符串S后面有没有再次出现子字符串P。
        if (j == n)
        {
            printf("%d ", i - n);
            j = ne[j];
        }
    }

    return 0;
}

PS:看不懂听不懂,自己手写一遍代码的过程就能懂了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值