831. KMP字符串(KMP,模板题,next数组详解)

2024-04-18 09:52

本文主要是介绍831. KMP字符串(KMP,模板题,next数组详解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

活动 - AcWing

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

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

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

输入格式

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

第二行输入字符串 P。

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

第四行输入字符串 S。

输出格式

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

数据范围

1≤N≤105
1≤M≤106

输入样例:
3
aba
5
ababa
输出样例:
0 2

解析: 

在介绍next数组之前先来引入两个概念:
一个字符串:c[1],c[2],c[3],c[4],c[5],……,c[n-3],c[n-2],c[n-1],c[n]
前缀:指从字符串的开头开始,一直到任意位置的连续子串,如:(c[1]),(c[1],c[2]),(c[1],c[2],c[3]),(c[1],c[2],c[3],c[4],c[5],……,c[n-3],c[n-2])等都是前缀

后缀:指从字符串的任意位置开始,一直到字符串的末尾的连续子串,如:(c[n]),(c[n-1],c[n]),(c[n-3],c[n-2],c[n-1],c[n]),(c[k],……,c[n-3],c[n-2],c[n-1],c[n])等,其中1<=k<=n-3.

最长公共前后缀:指一个字符串的前缀和后缀相同的最长长度。
举个例子,对于字符串 "abcabc", 它的前缀有:"a", "ab", "abc", "abca", "abcab", "abcabc",后缀有:"c", "bc", "abc", "cabc", "bcabc", "abcabc"。可以看到,"abc" 是既是前缀也是后缀的最长子串,它的长度为3,所以 "abcabc" 的LCPS为3。

现在就可以从dp的角度理解next数组了。
ne[i]:表示字符串中以 i 结尾的后缀与前缀构成的最长公共前后缀中前缀的结束位置

这个在字符串匹配中由于前缀和后缀一样,因此我们可以跳过前缀,直接从前缀结束的位置开始匹配,大大提高匹配的效率。

ne数组的预处理
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) {
            printf("%d ", i-n);//输出每次匹配成功的起始位置
            j = ne[j];
        }
}

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
#include<sstream>
#include<deque>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<double, double> PDD;
const int INF = 0x3f3f3f3f;
const LL Mod = 1e9;
const int N = 1e6 + 10, M = 1e5 + 10, P = 110;
int n, m;
int ne[N];
char s[N], p[N];int main() {scanf("%d%s", &n, p + 1);scanf("%d%s", &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;}/*cout << "________________" << endl << endl;for (int i = 1; i <= n; i++) {printf("%d ", ne[i]);}cout << endl;cout << endl;*/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) {printf("%d ", i-n);j = ne[j];}}return 0;
}

这篇关于831. KMP字符串(KMP,模板题,next数组详解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/914452

相关文章

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

SQL Server 中的 WITH (NOLOCK) 示例详解

《SQLServer中的WITH(NOLOCK)示例详解》SQLServer中的WITH(NOLOCK)是一种表提示,等同于READUNCOMMITTED隔离级别,允许查询在不获取共享锁的情... 目录SQL Server 中的 WITH (NOLOCK) 详解一、WITH (NOLOCK) 的本质二、工作

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用