AcWing 831. KMP字符串

https://www.acwing.com/problem/content/833/

#include <iostream>
using namespace std;
const int N = 10010, M = 100010;
int n, m;
int ne[N];
char s[M], p[N];
int main() {
    cin >> n >> p + 1 >> m >> s + 1;
    //求next过程
    //i从2开始,因为next[1]=0,如果第一个字母失败了,只能从0开始
    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;
    }
    //kmp匹配过程
    for (int i = 1, j = 0; i <= m; i ++ ) {
        while (j && s[i] != p[j + 1])    //当j没有退回起点,并且当前的s[i]不能和下一个j的位置匹配
            j = ne[j];//移动,保证之前的相等  直到匹配位置,或者j已经到开头了
        if (s[i] == p[j + 1]) //如果已经匹配了
            j ++ ;  //j往下移动
        if (j == n) {//说明匹配成果
            printf("%d ", i - n+1);
            j = ne[j];
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/QingyuYYYYY/p/11790107.html

时间: 2024-08-06 21:10:28

AcWing 831. KMP字符串的相关文章

831. KMP字符串(模板)

给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字. 模板串P在模式串S中多次作为子串出现. 求出模板串P在模式串S中所有出现的位置的起始下标. 输入格式 第一行输入整数N,表示字符串P的长度. 第二行输入字符串P. 第三行输入整数M,表示字符串S的长度. 第四行输入字符串S. 输出格式 共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开. 数据范围 1≤N≤1041≤N≤1041≤M≤1051≤M≤105 输入样例: 3 aba 5 ab

KMP字符串模式匹配详解

KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n);KMP匹配算法.可以证明它的时间复杂度为O(m+n).. 一.简单匹配算法 先来看一个简单匹配算法的函数: int Index_BF ( char S [ ], char T [ ], int pos ) { /* 若串 S 中从第pos(S 的下标0≤pos个字符 起存在和串 T 相同的子串,则称匹配成功,返回第一个 这样的子串在串 S 中的下标,否则返回 -1    */ int

KMP字符串匹配算法及next前缀数组的应用

#KMP字符串匹配算法及next前缀数组的应用------ KMP算法通常是我们学习字符串匹配算法时遇见的第一个算法,另外还有Rabin-Karp, Sunday算法等. 相对于其他字符串匹配算法, kmp在字符串中字符重复率低的情况下并不具备优势,那为什么KMP算法会作为经典的教学算法呢? 原因可能是:KMP算法充分利用next前缀数组的信息来优化算法,减小时间复杂度的思路在很多字符串相关问题中能给我们启发. 首先上KMP字符串匹配算法, [leetcode在线测试地址](https://le

(转)KMP字符串模式匹配详解

(转)KMP字符串模式匹配详解 个人觉得这篇文章是网上的介绍有关KMP算法更让人容易理解的文章了,确实说得很“详细”,耐心地把它看完肯定会有所收获的--,另外有关模式函数值next[i]确实有很多版本啊,在另外一些面向对象的算法描述书中也有失效函数 f(j)的说法,其实是一个意思,即next[j]=f(j-1)+1,不过还是next[j]这种表示法好理解啊: KMP字符串模式匹配详解 KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n)

KMP字符串

给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字. 模板串P在模式串S中多次作为子串出现. 求出模板串P在模式串S中所有出现的位置的起始下标. 输入格式 第一行输入整数N,表示字符串P的长度. 第二行输入字符串P. 第三行输入整数M,表示字符串S的长度. 第四行输入字符串S. 输出格式 共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开. 数据范围 1≤N≤1041≤N≤1041≤M≤1051≤M≤105 输入样例: 3 aba 5 ab

KMP字符串模式匹配算法(C++实现)

鉴于原理有点复杂,详细原理可以参考这篇文章http://blog.csdn.net/v_july_v/article/details/7041827 本文直接从结论入手,应付考试和竞赛足够了. 设T为目标串("aaabbbaabbabcabcabbaba"),pat为模式串("aabbabc"). 这是模式串的next数组: j(下标) 0 1 2 3 4 5 6 pat a a b b a b c next[j] -1 0 1 0 0 1 0 KMP算法: j=0

KMP字符串匹配算法——用最容易理解的方式描述

看了数据结构书上对于快速模式匹配算法KMP的介绍,感觉云里雾里.本文根据自己理解,并查资料整理了一种非常清晰简单的字符串匹配算法,并给予实现,自诩原创吧. 字符串匹配是我们经常要用到的一种算法,与普通的匹配算法相比KMP算法效率更高,时间复杂度为O(m+n).下面给予详细讲解: 概念详解 设原字符串为"BBC ABCDAB ABCDABCDABDE",待匹配字符串为"ABCDABD". 首先,字符串"BBC ABCDAB ABCDABCDABDE"

kmp字符串模式匹配算法

概述 ??kmp算法我觉得有两个关键点:1.计算模式字符串的部分匹配表(这时候,自己跟自己比较)2.匹配主串时候,主串字符只遍历一遍,匹配时候,根据模式串的部分匹配表计算模式串应该移动的位置.kmp算法时间复杂度为O(m+n);下面我实现的算法代码(PHP) 理论 关于kmp理论部分,这篇文章写得好:http://kb.cnblogs.com/page/176818/.我就不再赘述了. 计算部分匹配表 function kmp_next($string){ $length = strlen($s

KMP字符串匹配算法翔解?

那么首先我们知道,kmp算法是一种字符串匹配算法,那么我们来看一个例子. 比方说,现在我有两段像这样子的字符串: 分别是T和P,很明显,P比T的长度要短很多,我们要做的事情呢,就是找找T中有没有和P相同的一段. 如果按照最简单的办法来做匹配的话,我们一般是一个一个字母的来做. 像这样: 很显然,图中前面3位都是能匹配的,而第四位却不能匹配,怎么办? 这样: 我们就会将整个P字符串向右移动一格,又重新开始,从T中b处与P中第一个a处开始匹配. 如此往复,显然这样是很慢的,因为我们来考虑考虑这样一种