字符串匹配--(K)MP模板
大白书型模板,并没有写成函数形式:
关于p数组(失配指针数组)的含义: - 数组下标从0开始
p[i]表示当发现待匹配串(s)已匹配位置与模板串(t)的t[i]不匹配时,t中最近一个可以尝试继续匹配的位置。即当已经完成了s串与t[0]~t[i-1]的匹配时,发现s串后一个字符与t[i]不匹配,此时s串到当前不构成匹配的位置前可以视为与 t[0] ~ t[ p[i]-1 ] 完成了匹配,因此可以继续匹配s串当前字符与 t[ p[i] ] 。此时如果仍然不匹配可以继续对 t 当前不匹配的位置做失配转跳,直至转跳到t中的当前匹配位置为0位置。
因此实际上p[i]也具有这样的性质:t[0]~t[ p[i]-1 ] 是 t[0]~t[i-1] 的所有前缀中的最长可匹配后缀。
此外,对于一个长度为 m 的串自匹配,在此模板中 m-p[m] 就是这个串的最小循环节长度(最后一个循环可以不完整) - 数组下标从0开始
另一个关于自匹配后的失配指针的性质:对于该串的所有可以作为循环节的长度是:m-p[m] , m-p[p[m]] , m-p[p[p[m]]]……直到 p[x] = 0。 - 数组下标从0开始
这个是下标从0开始的:
#include <stdio.h>
#include <string.h>
typedef long long ll;
#define MP make_pair
#define PB push_back
const int mod = 1e9 + ;
const double eps = 1e-;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + ;
const int maxm = 1e5 + ; char s[maxn],t[maxm]; //s为待匹配串,t为模板串
int p[maxn]; //自匹配数组 int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s%s", t, s); //这个是字符串从下标0开始的
int i,j = ,ans=; // j = 0 注意, ans记录字符串出现次数
int n = strlen(s), m = strlen(t); //在题目中遇到过,其实strlen很慢,所以如果不先存起来可能有TLE的风险
p[] = p[] = ; //初始化自匹配数组
for(i = ; i < m ; ++ i){ //自匹配
while(j && t[i] != t[j])j = p[j];
if(t[i] == t[j])++ j;
p[i+] = j;
}
j = ; //注意 j=0
for(i = ; i < n ; ++ i){ //串匹配
while(j && s[i] != t[j])j = p[j];
if(s[i] == t[j])++ j;
if(j == m){
ans++; //此处记录出现次数(模板串在待匹配串中可重叠),或改为直接break表示是否出现过
}
}
printf("%d\n",ans);
}
return ;
}
数组下标从1开始:
#include<stdio.h>
#include<string.h> const int maxn=1e6+;
const int maxm=1e4+; char s[maxn],t[maxm];
int p[maxm]; int main(){
while(scanf("%s%s",s+,t+)!=EOF){ // 。。这个是从下标1开始的,恩修改的还是比较多的所以不是很建议
int i,j,ans=;
int n=strlen(s+),m=strlen(t+);
p[]=p[]=;
for(i=;i<=m;i++){
j=p[i];
while(j>&&t[i]!=t[j])j=p[j];
p[i+]=t[i]==t[j]?j+:;
}
j=;
for(i=;i<=n;i++){
while(j>&&s[i]!=t[j])j=p[j];
if(s[i]==t[j])j++;
if(j==m+){
ans++;
}
}
printf("%d\n",ans);
}
return ;
}
字符串匹配--(K)MP模板的更多相关文章
- 【Luogu P3375】字符串匹配KMP算法模板
Luogu P3375 模式串:即题目中的S2所代表的意义 文本串:即题目中的S1所代表的意义 对于字符串匹配,有一种很显然的朴素算法:在S1中枚举起点一位一位匹配,失配之后起点往后移动一位,从头开始 ...
- 字符串匹配--扩展KMP模板
对于一个字符串 s 以及子串 t ,扩展KMP可以用来求 t 与 s 的每个子串的最长公共前缀 ext [ i ],当然,如果有某个 ext 值等于 t 串的长度 lent ,那么就说明从其对应的 i ...
- 字符串匹配--manacher算法模板
manacher算法主要是处理字符串中关于回文串的问题的,它可以在 O(n) 的时间处理出以字符串中每一个字符为中心的回文串半径,由于将原字符串处理成两倍长度的新串,在每两个字符之间加入一个特定的特殊 ...
- 字符串匹配--AC自动机模板
AC自动机果断是神一样的东西,我赶在比赛前学习还是有用的,AC自动机最基本的是可以解决多个模式串在一个长字符串中出现的种类数或次数: 我暂时还是修改大神们的模板的昂 满满个人注释版帮助自己理解版: / ...
- P3375 【模板】KMP字符串匹配 (KMP模板)
题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next. (如果你不知道这是什么意思也不要问,去百度 ...
- P3375 模板 KMP字符串匹配
P3375 [模板]KMP字符串匹配 来一道模板题,直接上代码. #include <bits/stdc++.h> using namespace std; typedef long lo ...
- 字符串KMP——用途广泛的字符串匹配算法 + 扩展KMP——特殊定义的字符串匹配
引 入 引入 引入 " SY 和 WYX 在看毛片.(几 毛 钱买到的动作 片,毛 片) WYX 突然想回味一个片段,但是只记得台词里面有一句挺长的 " ∗ ∗ ∗ ∗ **** ...
- 洛谷—— 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 ...
随机推荐
- Unity项目中显示项目的FPS
using UnityEngine; using System.Collections; public class ShowFpsOnGUI : MonoBehaviour { public floa ...
- 显示Unicode 字节的对应字符的小技巧
在一段smali代码里看到这样的代码 const-string v0, "\u7528\u6237\u9a8c\u8bc1\u8fc7\u671f\uff0c\u8bf7\u91cd\u65 ...
- git查看本地分支关联(跟踪)的远程分支之间的对应关系,本地分支对应哪个远程分支
git branch -vv: [root@realserver git-test]# git branch -vv bug 23043a7 add new.txt master.* dev ...
- P2048 [NOI2010]超级钢琴 (RMQ,堆)
大意: 给定n元素序列a, 定义一个区间的权值为区间内所有元素和, 求前k大的长度在[L,R]范围内的区间的权值和. 固定右端点, 转为查询左端点最小的前缀和, 可以用RMQ O(1)查询. 要求的是 ...
- hpu积分赛(回溯法)
问题 : 不开心的小明① 时间限制: 1 Sec 内存限制: 128 MB 提交: 2 解决: 1 题目描述 一天, 小明很不开心,先是向女神表白被拒, 数学又考了0分, 回家的路上又丢了钥匙, 他非 ...
- Java IO流中的flush()
通过BufferedOutputStream或BufferedWriter 链接到底层流上来实现.因此,在写 完数据时,flush就显得尤为重要. 例如: 上图中WEB服务器通过输出流向客户端响应了一 ...
- CSS样式属性——背景
背景——包括背景颜色.背景图片,以及背景图片的控制 background-color:设置背景色(transparent表示透明的背景色) background-image:设置元素的背景图片 ba ...
- 用js实现个优先队列吧
队列是一种很常用的数据结构,它是一组遵循先进先出(FIFO)规则的项.在现实生活中,最常见的队列的例子就是排队.队列有一些方法,入队.出队.队列的长度,清空队列等.用js实现一个普通的队列代码如下: ...
- Snagit安装步骤
Snagit安装步骤 1解压文件 2运行文件下一步下一步 3拷贝汉化文件到安装目录 安装目录 D:\home\user\TechSmith\snagit 成功
- Linux WiFi Deauthenticated Reason Codes
Code Reason Explanation 0 Reserved Normal working operation 1 Unspecific Reason We don’t know what’s ...