KMP算法讲解
老规矩,讲算法前,先说一道小问题吧
给你一个长串和短串,求短串在长串中出现的次数和位置。
设长串长度为len1,短串长度为len2。
如果len1*len2<=108,那就很简单了,直接暴力枚举以每个字符为开始的字符串是否匹配即可,复杂度为O(len1*len2);(是不是感觉太大了?)
如果将数据范围扩大到len1,len2<-106呢?
现在就开始介绍我们的KMP算法。
有了前面的问题,KMP要解决的是什么就自然出来了,KMP的复杂度达到的耸人听问的O(len1+len2)。
我们可以想想我们相对于暴力算法需要改进什么?
我们可以每一次失配(也就是匹配失败)的时候,不用每一次都从上一次的出发点只往后移动一个字符,可以跳啊!
我们可以预处理出每一次跳的位置来有利于节省复杂度啊。
这里我们就讲一讲怎么跳,以及怎么进行预处理。
1.怎么跳?
我们假设字符串为abaaba
我们如果在第二个a时失配了,我们应该怎么往前呢?
我们就可以可以把第一个a放在这一个位置继续匹配。
那么,如果是第四个a呢?
我们是不是就可以把第二个a放在这个位置呢?
大家可以看到,第最后一个字符到第三个a的字符串是aba,而第一个字符到第二个a的字符串是不是也是aba,它们不是一样的吗?
讲到这里,大家应该大概的明白了KMP是怎么跳的了吧。
我们记一个nxt数组,nxt[i]表示的是从第一个字符到第i个字符的最长前后缀的长度。看不懂没关系,举个例子。
假设字符串为abaaba
nxt[0]=0
nxt[1]=0(ab无前后缀)
nxt[2]=1(aba最长前后缀为a)
nxt[3]=1(abaa-----a)
nxt[4]=0(abaab--无)
nxt[5]=3(abaaba-aba)
2.初始化
问题来了,怎么用很少的时间复杂度来进行初始化呢?
很容易想到递推,怎么递推呢?
我们假设求出了前面的nxt,现在多了一个,我们就应该找一找了。
我们可以跳前一个位置的nxt,直到跳到一个位置后面有一个字符是所需要的,是那里的后面那一个字符。
每个这样递推就好了!
而查找的过程与初始化的过程类似,这里就不再赘述了。
下面上一份模板代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s1[],s2[];
int nxt[];
int main()
{
scanf("%s",s1);
scanf("%s",s2);
nxt[]=;
int len1=strlen(s1);
int len2=strlen(s2);
for(int i=,k=;i<len2;i++)
{
k=nxt[i-];
while(k>&&s2[k]!=s2[i]) k=nxt[k-];
if(s2[k]==s2[i]) k++;
nxt[i]=k;
}
for(int i=,j=;i<len1;i++)
{
while(j!=&&s1[i]!=s2[j]) j=nxt[j-];
if(s1[i]==s2[j]) j++;
if(j==len2)
{
printf("%d\n",i-j+);
}
}
for(int i=;i<len2;i++) printf("%d ",nxt[i]);
return ;
}
模板题:https://www.luogu.org/problemnew/show/3375
感谢大家的支持!
如果有不足之处,请尽管提出,本人不胜感激!
KMP算法讲解的更多相关文章
- 串的应用与kmp算法讲解--学习笔记
串的应用与kmp算法讲解 1. 写作目的 平时学习总结的学习笔记,方便自己理解加深印象.同时希望可以帮到正在学习这方面知识的同学,可以相互学习.新手上路请多关照,如果问题还请不吝赐教. 2. 串的逻辑 ...
- (转载)KMP算法讲解
网上找到了一篇详细讲解KMP字符串匹配算法,质量很高.特备忘于此. 摘自:http://blog.csdn.net/v_july_v/article/details/7041827 实现代码如下: / ...
- [转]KMP算法理解及java实现
这大概是我看的最好懂的KMP算法讲解了,不过我还只弄懂了大概思想,算法实现我到时候用java实现一遍 出处:知乎 https://www.zhihu.com/question/21923021/ans ...
- 【原创】通俗易懂的讲解KMP算法(字符串匹配算法)及代码实现
一.本文简介 本文的目的是简单明了的讲解KMP算法的思想及实现过程. 网上的文章的确有些杂乱,有的过浅,有的太深,希望本文对初学者是非常友好的. 其实KMP算法有一些改良版,这些是在理解KMP核心思想 ...
- BF、KMP、BM、Sunday算法讲解
BF.KMP.BM.Sunday算法讲解 字串的定位操作通常称作串的模式匹配,是各种串处理系统中最重要的操作之一. 事实上也就是从一个母串中查找一模板串,判定是否存在. 现给出四种匹配算法包括BF(即 ...
- POJ 3461 Oulipo[附KMP算法详细流程讲解]
E - Oulipo Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit ...
- 字符串匹配KMP算法的讲解C++
转自http://blog.csdn.net/starstar1992/article/details/54913261 也可以参考http://blog.csdn.net/liu940204/art ...
- KMP算法入门讲解
字符串匹配问题.假设文本是一个长度为$n$的字符串$T$,模板是一个长度为$m$的字符串$P$,且$m\leq n$.需要求出模板在文本中的所有匹配点$i$,即满足$T[i]=P[0],T[I+1]= ...
- 串匹配算法讲解 -----BF、KMP算法
参考文章: http://www.matrix67.com/blog/archives/115 KMP算法详解 http://blog.csdn.net/yaochunnian/artic ...
随机推荐
- PHP运算符优先级 运算符分类
运算符 运算符是可以通过给出的一或多个值(用编程行话来说,表达式)来产生另一个值(因而整个结构成为一个表达式)的东西. 运算符可按照其能接受几个值来分组.一元运算符只能接受一个值,例如 !(逻辑取反运 ...
- RobotFramework自动化测试框架-移动手机自动化测试Element Attribute Should Match关键字的使用
Element Attribute Should Match 关键字用来判断元素的属性值是否和预期值匹配,该关键字接收四个参数[ locator | attr_name | match_pattern ...
- Linux下实现视频读取(三)---Buffer的准备和数据读取
前面主要介绍的是:V4L2 的一些设置接口,如亮度,饱和度.曝光时间,帧数,增益.白平衡等.今天看看V4L2 得到数据的几个关键ioctl,Buffer的申请和数据的抓取. 1. 初始化 Memory ...
- Java后台实现方法
Java后台实现方法 首先后台结构分为四个部分(以表schedule为例) entity>mapper>service>controller 1. 在entity里面写好实体,新建目 ...
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)
题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...
- ASP.NET Core 中间件(Middleware)详解
什么是中间件(Middleware)? 中间件是组装到应用程序管道中以处理请求和响应的软件. 每个组件: 选择是否将请求传递给管道中的下一个组件. 可以在调用管道中的下一个组件之前和之后执行工作. 请 ...
- REST设计规则
1.简介 REST(Representational State Transfer), 表述性状态转移是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格. REST只是一 ...
- 使用Mkdocs构建你的项目文档
使用Mkdocs构建你的项目文档 环境搭建 安装必需软件 作者是在windows下安装的,如果是linux或mac用户,官网有更详细的安装说明. windows 10 x64 当然还有广大的windo ...
- mysql中对字符集和校对规则的认识
字符集:指符号和字符编码的集合.校对规则:比较字符编码的方式.GBK2312:主要包括简体中文字符及常用符号,对于中文字符采用双字节编码的格式,也就是说一个汉字字符在存储占两个字节.GBK:包括有中. ...
- 查看Flink的Job Graph时的问题
Flink运行Job时,可以通过Job Graph看到执行计划,但是如果用IE,会被坑: 换成谷歌Chrome,就OK了: 这个Job Grap,好像是SVG的,可能是IE不支持SVG,需要安装插件才 ...