KMP
  8U5rtRnsia4G 2023年11月30日 20 0

一、算法描述

本篇文章水平不够,讲不清楚KMP到底是怎么回事,以后再更新一下。

本篇文章讲述的是KMP算法, 一个著名的字符串匹配算法,效率很高,\(O(n)\) 的时间复杂度。

难点在于:如何理解 \(next[i]\) ★★★

\(ne[i] = j\) 表示,\(p[1 ~ j] = p[i - j + 1, i]\),从 \(1\)\(j\) 的前缀串,完全等于,从 \(i - j + 1\)\(i\) 的后缀串。

当匹配道某一位置时,下一个位置不匹配,此时为了节约时间,我们要找到一个位置,使得,匹配不成功的点能够继续匹配

暴力做法是往后移动一位,而KMP是直接滑到能够滑到的最远的位置,或者说最少回退多少能够继续匹配。

二、题目描述

给定一个字符串 \(S\),以及一个模式串 \(P\),所有字符串中只包含大小写英文字母以及阿拉伯数字。

模式串 \(P\) 在字符串 \(S\) 中多次作为子串出现。

求出模式串 \(P\) 在字符串 \(S\) 中所有出现的位置的起始下标。

输入格式

第一行输入整数 \(N\),表示字符串 \(P\) 的长度。

第二行输入字符串 \(P\)

第三行输入整数 \(M\),表示字符串 \(S\) 的长度。

第四行输入字符串 \(S\)

输出格式

共一行,输出所有出现位置的起始下标(下标从 \(0\) 开始计数),整数之间用空格隔开。

数据范围

\(1≤N≤10^5\)
\(1≤M≤10^6\)

输入样例:

3
aba
5
ababa 

输出样例:

0 2 

三、题目来源

AcWing算法基础课-831.KMP字符串

四、源代码

#include <iostream>

using namespace std;

const int N = 100010, M = 1000010;

int n, m;
char p[N], s[M];
int ne[N];

int main()
{
    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 - n << ' ';
            j = ne[j];
        }
    }
    
    return 0;
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月30日 0

暂无评论

推荐阅读
  jTMfQq5cr55P   2024年05月17日   44   0   0 算法与数据结构
  jTMfQq5cr55P   2024年05月17日   40   0   0 算法与数据结构
8U5rtRnsia4G
作者其他文章 更多