模式匹配KMP POJ 3461

本文详细介绍了KMP算法的原理及应用,通过解决在指定长度限制内查找子串出现次数的问题,展示了算法的时间复杂度优势。文章还分享了作者的学习感悟,鼓励读者深入学习算法,享受学习过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址:http://poj.org/problem?id=3461


题目大意:在T串中找出W串出现的次数,T串的长度小于等于1000000,W串的长度小于等于10000。


解题思路:赤裸裸地KMP,可是最近果真总是作死的节奏,一直感觉我对地址下标、数字神马的比较敏感,今天卡了将近一个小时。。。


程序代码:

/*
算法时间复杂度:O(m+n),m、n分别为两个串的长度。
与传统算法的区别就是:每一趟匹配过程中出现字符比较不等时,
                       不需回溯主串中用来指示字符的i指针
                       而是利用已经得到的“部分匹配”的结果
                       将模式串向右滑动尽可能远的距离,再进行比较。
next[j]数组:表明当模式串中第j个字符与主串中第i个字符不匹配时,
             在模式中需重新和该字符进行比较的字符的位置。

*/

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

const int M = 1000010;

char w[M];
char t[M];
int next[M];

void Init(int w_len)
{
    next[0] = -1;
    int i = 0, j = -1;
    while (i < w_len)
    {
        if (j == -1 || (w[i] == w[j]))
        {
            i++;
            j++;
            next[i] = j;
        }
        else j = next[j];
    }

}

int Kmp(int w_len, int t_len)
{
    int i = 0, j = 0;
    int cnt = 0;
    while (i < t_len)
    {
        if (j == -1 || (t[i] == w[j]))
        {
            i++;
            j++;
        }
        else
        {
            j = next[j];
        }

        if (j >= w_len)
        {
            cnt++;
        }
    }
    return cnt;

}
int main()
{
    int ncase;
    scanf("%d", &ncase);
    for (int i = 0; i < ncase; i++)
    {
        scanf("%s %s", w, t);
        int w_len = strlen(w);
        int t_len = strlen(t);
        Init(w_len);
        int ans = Kmp(w_len, t_len);
        printf("%d\n", ans);
    }
    return 0;
}

一点感悟:曾经要是好好静下心来学算法,不是盲目地刷题,该是多好~~    学习算法是件快乐的事情,加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值