P3375【模板】KMP字符串匹配
前言:
额……很久以前就写了KMP模板(只是半知不解),话说看完了manacher,再回过头看KMP,是真TM简单啊!字符串专题整体较抽象,所以必须牢记思路并时常复习
题目描述
如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。
为了减少骗分的情况,接下来还要输出子串的前缀数组next。
(如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了。)
输入输出格式
输入格式:
第一行为一个字符串,即为s1
第二行为一个字符串,即为s2
输出格式:
若干行,每行包含一个整数,表示s2在s1中出现的位置
接下来1行,包括length(s2)个整数,表示前缀数组next[i]的值。
输入输出样例
ABABABC
ABA
1
3
0 0 1
说明
时空限制:1000ms,128M
数据规模:
设s1长度为N,s2长度为M
对于30%的数据:N<=15,M<=5
对于70%的数据:N<=10000,M<=100
对于100%的数据:N<=1000000,M<=1000000
样例说明:
所以两个匹配位置为1和3,输出1、3
Solution:
什么是字符串匹配:
简单来讲,就是给定两个字符串,判断长度较短的字符串是否是长字符串的子串,并输出第一次出现的位置。
暴力解法:
用两个下标分别表示当前匹配到的主串和模式串的位置,每次移动主串和模式串的下标并匹配,不匹配时主串回到上个下标的后一个位置,模式串从头开始匹配,不停进行直到模式串下标越界说明匹配成功。这样暴力的复杂度是$O(mn)$,比如(主串:aaaaaaaaab 模式串:ab 暴力匹配显然要在主串上移动下标$n$次且每次模式串移动下标$m$次)
kmp的作用:
我们从暴力解法中,容易看出每次匹配失败后,主串下标的移动和模式串下标的重置使得效率变低。而$KMP$能避免多余的下标移动,使得主串下标每次不回退,模式串直接从上次失配的位置开始匹配,这样使复杂度变成$O(m+n)$。
具体思想:
我们预处理出模式串的从头开始的各子串的最长公共前后缀,当模式串在某一位置失配时,直接将模式串移动到已经匹配的模式串子串的最长公共前后缀的位置并使他们重叠,这样便能防止不必要的移动减损效率。
而预处理$next$数组时,实际上就是一个线性的$dp$,因为我们发现每增加$1$个字符,最长公共前后缀的改变会和前面处理出的$next$有关,举个例子:aba 的最长公共前后缀为$1$,当变为abab时,只需判断新增的b和开始的第$1+1$个字符是否相同。这样就是一个线性递推的过程,但是具体实现时有一些细节,举举例子就能知道了。
讲的不够清楚,网上的博客还行,可以去$B$站看下这个视频
代码:
#include<bits/stdc++.h>
#define il inline
#define ll long long
using namespace std;
int next[],m,n;
char s1[],s2[];
il void getnext(char *s2){
for(int i=;i<m;i++){
int j=i;
while(j){
j=next[j];
if(s2[j]==s2[i]){next[i+]=j+;break;}
}
}
}
int main()
{
scanf("%s%s",s1,s2);
n=strlen(s1),m=strlen(s2);
getnext(s2);
int j=;
for(int i=;i<n;i++){
while(j&&s1[i]!=s2[j])j=next[j];
j+=s1[i]==s2[j]?:;
if(j==m)printf("%d\n",i-m+);
}
for(int i=;i<=m;i++)printf("%d ",next[i]);
return ;
}
P3375【模板】KMP字符串匹配的更多相关文章
- P3375 模板 KMP字符串匹配
P3375 [模板]KMP字符串匹配 来一道模板题,直接上代码. #include <bits/stdc++.h> using namespace std; typedef long lo ...
- 洛谷P3375 [模板]KMP字符串匹配
To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...
- 算法模板——KMP字符串匹配
功能:输入一个原串,再输入N个待匹配串,在待匹配串中找出全部原串的起始位置 原理:KMP算法,其实这个东西已经包含了AC自动机的思想(fail指针/数组),只不过适用于单模板匹配,不过值得一提的是在单 ...
- [模板]KMP字符串匹配
洛谷P3375 注意:两次过程大致相同,故要熟读熟记,切勿搞混 可以看看其他的教程:http://www.cnblogs.com/c-cloud/p/3224788.html 本来就不太熟,若是在记不 ...
- [模板] KMP字符串匹配标准代码
之前借鉴了某个模板的代码.我个人认为这份代码写得很好.值得一背. #include<bits/stdc++.h> using namespace std; const int N=1000 ...
- P3375 【模板】KMP字符串匹配
P3375 [模板]KMP字符串匹配 https://www.luogu.org/problemnew/show/P3375 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在 ...
- 洛谷—— P3375 【模板】KMP字符串匹配
P3375 [模板]KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next. (如 ...
- KMP字符串匹配 模板 洛谷 P3375
KMP字符串匹配 模板 洛谷 P3375 题意 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.(如果 ...
- 洛谷P3375 - 【模板】KMP字符串匹配
原题链接 Description 模板题啦~ Code //[模板]KMP字符串匹配 #include <cstdio> #include <cstring> int cons ...
- Luogu 3375 【模板】KMP字符串匹配(KMP算法)
Luogu 3375 [模板]KMP字符串匹配(KMP算法) Description 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来 ...
随机推荐
- Golang定时器断续器
定时器 1.定时器结构 结构定义 type Timer struct { C <-chan Time // 接受定时器事件的通道 r runtimeTimer } type runtimeTim ...
- Eclipse中各种文件的注释与取消注释的快捷键
Eclipse中各种文件的注释与取消注释的快捷键 Java文件: 注释和取消注释的快捷键都是:CTRL + / 或 Shift+Ctrl+C JS文件: 注释和取消注释的快捷键都是:CTRL + / ...
- java 时间转换去杠
public static String minusHyphen(String dateParam){ if(dateParam ==null) return null; if(dateParam.i ...
- Java中Redis缓存
1:安装 安装可分为单机版redis 和集群版redis 安装比较简单,自行百度即可 2:集成 pom文件中加入jedis 依赖,spring创建redis的application-resid配置, ...
- java对接微信支付
对接微信扫码支付(模式2),前端使用velocity技术 (1)调用微信支付接口(view层) 此部分业务逻辑部分可以省略 @RequestMapping("/wxpay.htm" ...
- webpack和sass功能简介
1.webpack webpack 是一个打包工具,为什么需要打包?因为有的人的脚本开发语言可能是 CoffeeScript 或者是 TypeScript,样式开发工具可能是 Less 或者 Sass ...
- Mysql基础2-数据定义语言DDL
主要: 数据库操作语句 数据表操作语句 视图定义语句 数据库表设计原则 DDL: Data Definition Language 数据定义语言 数据库操作语句 创建库 创建数据库: create d ...
- Volatile的详解
volatile关键字修饰的共享变量主要有两个特点:1.保证了不同线程访问的内存可见性 2.禁止重排序 在说内存可见性和有序性之前,我们有必要看一下Java的内存模型(注意和JVM内存模型的区分 ...
- 初步学习pg_control文件之五
接前文 初步学习pg_control文件之四,继续看何时出现 DB_IN_CRASH_RECOVERY: 看下面代码就比较清楚了:如果对 InArchiveRecovery 判断值为假,而且 读取出 ...
- Hibernate-ORM:03.Hibernate主键生成策略
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 此篇博客简单记录五种常用的主键生成策咯: 不同的主键生成策略,生成的sql语句,以及hibernate的操作都 ...