KMP字符串匹配学习笔记
部分内容引自皎月半洒花的博客
模式串匹配问题模型
给定一个需要处理的文本串和一个需要在文本串中搜索的模式串,查询在该文本串中,给出的模式串的出现有无、次数、位置等。
算法思想
每次失配之后不会从头开始枚举,而会从最大可能匹配位置开始重新匹配
考虑数据
模式串:abcabc
文本串:abcabdababcabc
匹配过程中文本串的$d$和模式串末位的$c$出现了失配,由目前的匹配结果可知模式串的前五位$abcab$与文本串失配位置前的五位匹配,取模式串中匹配的部分$S$,对于$S$中任何相同的前缀和后缀,显然该前缀一定与文本串失配位置前的若干位匹配,取满足上述条件的最大前缀与文本串匹配,再尝试重新匹配下一位(这一位置即为最大可能匹配位置),重复该过程直到匹配成功或不存在这样的前缀时结束
模式串: abcabc
文本串:abcabdababcabc
$next$数组
$next[i]$表示前$i-1$位(从第0位开始)匹配而第$i$位失配时应跳转到的位置,该位置满足前$next[i]-1$位仍与文本串匹配
$next$数组的处理
自匹配,使模式串与自身进行匹配,匹配过程中处理出下一位的$next$值,即当前位的最大匹配
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e6+10;
char s[maxn],st[maxn];
int n,m,nxt[maxn];
void getnext() //自匹配(next数组的处理)
{
for(int j=0,i=1;i<m;i++)
{
while(j&&s[i]!=s[j])
j=nxt[j];
nxt[i+1]=(j+=s[i]==s[j]);
//若i,j位置匹配成功,显然s[1~j]是s[1~i]的最大的,满足前后缀相等的前缀,则j+1为s[i]的最大可能匹配位置
//否则j必为0,意为没有任何成功的匹配
}
}
int main()
{
scanf("%s%s",st,s);
n=strlen(st),m=strlen(s);
getnext();
for(int j=0,i=0;i<n;i++)
//i为文本串位置,j为模式串当前尝试匹配的位置
{
while(j&&st[i]!=s[j])
//重复取最大可能匹配位置,直到匹配成功或不存在任何可能的匹配
j=nxt[j];
if(st[i]==s[j])//若匹配成功,模式串尝试匹配的位置后移一位
if(++j==m)
{
printf("%d\n",i-j+2);
j=nxt[j];
//若匹配成功则统计答案并重置匹配位置
}
}
for(int i=1;i<=m;i++)
printf("%d ",nxt[i]);
printf("\n");
return 0;
}
KMP字符串匹配学习笔记的更多相关文章
- KMP字符串匹配学习
KMP字符串匹配学习 牛逼啊 SYC大佬的博客
- Luogu 3375 【模板】KMP字符串匹配(KMP算法)
Luogu 3375 [模板]KMP字符串匹配(KMP算法) Description 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来 ...
- 洛谷P3375 [模板]KMP字符串匹配
To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...
- 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.(如果 ...
- {Reship}{KMP字符串匹配}
关于KMP字符串匹配的介绍和归纳,作者的思路非常清晰,推荐看一下 http://blog.csdn.net/v_july_v/article/details/7041827
- 洛谷P3375 - 【模板】KMP字符串匹配
原题链接 Description 模板题啦~ Code //[模板]KMP字符串匹配 #include <cstdio> #include <cstring> int cons ...
- P3375 模板 KMP字符串匹配
P3375 [模板]KMP字符串匹配 来一道模板题,直接上代码. #include <bits/stdc++.h> using namespace std; typedef long lo ...
随机推荐
- You Don't Know the Hack tech in the frontend development
You Don't Know the Hack tech in the frontend development 你所不知道的前端黑科技 css in js animation https://www ...
- taro coding specification
taro coding specification https://nervjs.github.io/taro/docs/spec-for-taro.html 跨平台开发 https://nervjs ...
- js 的 ArrayBuffer 和 dataView
arrayBuffer文档 一个十六进制代表4位,0xF = 1111,0xFF = 1111 1111,八位是1字节,所以通常用两个16进制代表1字节. 假如我申请一个8字节的内存空间,然后初始化为 ...
- C++算法代码——众数
好久没更新了-- 题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1615 题目描述 N 个 1 到 30000 间无序数正整数,其中 ...
- 死磕以太坊源码分析之EVM指令集
死磕以太坊源码分析之EVM指令集 配合以下代码进行阅读:https://github.com/blockchainGuide/ 写文不易,给个小关注,有什么问题可以指出,便于大家交流学习. 以下指令集 ...
- Docker 镜像加速教程
原文链接:https://fuckcloudnative.io/posts/docker-registry-proxy/ 在使用 Docker 和 Kubernetes 时,我们经常需要访问 gcr. ...
- mysql索引设计的注意事项(大量示例,收藏再看)
mysql索引设计的注意事项(大量示例,收藏再看) 目录 一.索引的重要性 二.执行计划上的重要关注点 (1).全表扫描,检索行数 (2).key,using index(覆盖索引) (3).通过ke ...
- 用于功率集成电路应用的600伏、10安、4H-SIC横向单沟道金属氧化物半导体场效应晶体管的演示和分析
用于功率集成电路应用的600伏.10安.4H-碳化硅横向单沟道金属氧化物半导体场效应晶体管的演示和分析 摘要: 本文报道了一个具有大电流处理能力(10 A)的600伏4H-碳化硅横向场效应晶体管的演示 ...
- 剑指 Offer 68 - II. 二叉树的最近公共祖先 + 最近公共祖先(LCA)
剑指 Offer 68 - II. 二叉树的最近公共祖先 Offer_68_2 题目详情 题解分析 java代码 package com.walegarrett.offer; /** * @Autho ...
- 自己动手实现springboot运行时新增/更新外部接口
最近有个需求:需要让现有springboot项目可以加载外部的jar包实现新增.更新接口逻辑.本着拿来主义的思维网上找了半天没有找到类似的东西,唯一有点相似的还是spring-loaded但是这个东西 ...