【Luogu P3375】字符串匹配KMP算法模板
- 模式串:即题目中的S2所代表的意义
- 文本串:即题目中的S1所代表的意义
对于字符串匹配,有一种很显然的朴素算法:在S1中枚举起点一位一位匹配,失配之后起点往后移动一位,从头开始进行匹配。
这种算法的时间复杂度几乎达到了\(O(nm)\),显然是不能接受的。
这种做法的缺点在于做了很多无用的匹配,并且每一次都从头开始匹配,完全忽略上一次匹配的信息。
而KMP算法就利用了上一次匹配的信息,减少匹配次数,时间复杂度仅有\(O(n)\)

(图片来自算法导论)
观察这样一张图。在第六位失配之后,按照朴素算法,我们把模式串后移一位,从头开始匹配。事实上后移一位的匹配根本不可能成功,根据上一次匹配得到的信息,因为文本串(灰色部分)中的第二位能够与模式串的第二位匹配,所以不可能与第一位匹配。而文本串(灰色部分)第三四五位恰好与模式串的第一二三位匹配,所以我们可以直接把模式串后移两位,重新开始匹配。

(图片来自算法导论)
如上图所示,这样可以减少很多不必要的匹配。
那么我们怎么才能知道让模式串偏移多少才合适呢?
下文的j是在模式串中的指针,j及其以前的字符是已经匹配的。
假设字符串在第j位失配,我们要找到一个尽可能长的长度\(L\),使\(S2[1..L]\)与\(S2[j-L,j]\)完全匹配(L<j),这样我们就可以在可以直接令\(j=L\),跳过前面L个的字符,因为他们绝对是匹配的。
结合代码及注释进行透彻的理解:(从KMP函数开始看更便于理解)
#include<cstdio>
#include<iostream>
using namespace std;
string s1,s2;
int nxt[1000005];
void Pre_do()
{
int len=s2.size();
nxt[0]=-1;//-1意味着从头开始匹配
for (int i=1,j=-1;i<len;i++)//注意i从1开始
{
while (j>=0&&s2[j+1]!=s2[i]) j=nxt[j];//假设不能匹配就跳过去。
//j一定小于i,所以此时的nxt[j]一定已经被记录了
if (s2[j+1]==s2[i]) j++;//匹配了就增加匹配长度
nxt[i]=j;//记录
}
}
int KMP()
{
int ret=0,len1=s1.size(),len2=s2.size();
for (int i=0,j=-1;i<len1;i++)
{
while (j>=0&&s2[j+1]!=s1[i]) j=nxt[j];//假设不能匹配就跳过去。
if (s2[j+1]==s1[i]) j++;//匹配了就增加匹配长度
if (j==len2-1) //匹配成功
{
ret++;
j=nxt[j];
printf("%d\n",i-len2+2);
}
}
return ret;
}
int main()
{
cin>>s1>>s2;
Pre_do();//预处理,求出每个位置失配后应该跳到哪个位置
KMP();
int len2=s2.size();
for (int i=0;i<len2;i++) printf("%d ",nxt[i]+1);
return 0;
}
【Luogu P3375】字符串匹配KMP算法模板的更多相关文章
- 字符串匹配KMP算法详解
1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有比较详细的通俗易懂的讲解,另一方面也怪自己没有沉下心来研究.最近在leetcode上又遇见字符串匹配的题目,以此 ...
- 字符串匹配KMP算法
1. 字符串匹配的KMP算法 2. KMP算法详解 3. 从头到尾彻底理解KMP
- 字符串匹配--kmp算法原理整理
kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...
- 字符串匹配KMP算法的C语言实现
字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...
- 字符串匹配KMP算法的讲解C++
转自http://blog.csdn.net/starstar1992/article/details/54913261 也可以参考http://blog.csdn.net/liu940204/art ...
- 字符串匹配KMP算法(转自阮一峰)
转自 http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 字符串匹配是计算 ...
- 字符串匹配——KMP算法
关于KMP算法的分析,我觉得这两篇博客写的不错: http://www.ruanyifeng.com/blog/2013/05/Knuth–Morris–Pratt_algorithm.html ht ...
- 字符串匹配—KMP算法
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特-莫里斯-普拉特操作(简称KMP算法).KMP算法的核心是利用匹配失败后 ...
- P3375 【模板】KMP字符串匹配——kmp算法
先上一波题目 https://www.luogu.org/problem/P3375 kmp模板 看了好久才想起来是个什么东西qwq #include<cstdio> #include&l ...
随机推荐
- 使用IDEA开发Spark程序
一.分布式估算圆周率 1.计算原理 假设正方形的面积S等于x²,而正方形的内切圆的面积C等于Pi×(x/2)²,因此圆面积与正方形面积之比C/S就为Pi/4,于是就有Pi=4×C/S. 可以利用计算机 ...
- 第七篇 Flask实例化配置及Flask对象配置
一.Flask对象的配置 Flask 是一个非常灵活且短小精干的web框架 , 那么灵活性从什么地方体现呢? 有一个神奇的东西叫 Flask配置 , 这个东西怎么用呢? 它能给我们带来怎么样的方便呢? ...
- 新的服务器安装的mysql使用navcat连接不上
首先出现问题 然后在防火墙添加3306端口 /sbin/iptables -I INPUT -p tcp --dport 3306 -j ACCEPT 又出现了问题 ERROR 1130: Host ...
- MySQL:数据库基本认识
1.什么是数据库 通俗来讲,数据库就是用于存储数据的仓库.很多人可能会问,存储数据用文件不就行了吗?为什么还要弄数据库? 文件存储数据具有以下几个缺点: 文件的安全性问题 文件不利于查询和数据库管理 ...
- mybatis-spring 启动过程和调用过程
mybatis-spring 可以为我们做什么 mybatis框架已经很不错了,它把配置和执行sql的通用过程抽象出来.只要你符合mybatis框架的要求,首先有正确的配置,然后有model,inte ...
- 医生智能提醒小程序数据库设计心得——Legends Never Die
数据库设计心得 根据我们小组数据库设计的整个流程,我们将整个数据库设计划分为两个具体的阶段,在每个阶段需要进行不同的准备,有不同的注意事项,接下来我们将结合在数据库设计过程中遇到的一些问题和困难,提出 ...
- Kong04- Kong 四大参考说明
Kong 四大参考说明 Kong 的官方有很多详细的参考说明,比如配置文件.命令行.Admin API.代理.负载均衡,接下来我们简单看一下,都提供什么内容. 本文主要基于 Kong 1.3 版本进行 ...
- Kong02-KongA 介绍
KongA 是 Kong 的一个 GUI 工具.GitHub 地址是 https://github.com/pantsel/konga . KongA 概述 KongA 带来的一个最大的便利就是可以很 ...
- CSPS模拟 79
T1 建一颗新树,倍增 T2 WARNING:竞赛图如果有环,则最小环一定为三元环 (发现这个结论的这把都稳了) 然后三元环计数,发现部分分都是为了审出题意但是不会正解的人设的.. 由于对于任意一种方 ...
- 关于css布局的一点记录
1 关于css实现水平垂直居中的一些方法: .css的定位:用margin,padding,position position:absolute; //绝对定位,一般父级元素采用relative来 ...