KMP算法 详解+模板
本文大部分摘自szy学长的ppt《string》中的KMP部分。
%%%膜拜szy大神orz
1.概述
KMP 算法是用来解决单模匹配问题的一种算法。
如果暴力的进行单模匹配,那么时间复杂度为O(nm)。
KMP 算法通过对模式串的预处理优化了复杂度。
2.求next数组
为了叙述方便,设模式串长度为n,主串长度为m。
将模式串称为s1,主串称为s2,下标从1 开始。
我们首先对模式串预处理出一个next 数组。
next[i] 表示最大的x,满足s1[1 : x - 1] 是s1[1 : i - 1] 的后缀。
这个数组记录了失配时,模式串指针移动的目标位置。
求next[i] 时,考虑维护一个位置j,初始时为next[i - 1]。
如果s1[j] = s1[i -1],那么next[i] 显然等于j + 1。
如果s1[j] != s1[i - 1],那么此时需要将j 向前移动到next[j] 的位置。
一直将j 移动到next[j] 的位置,直到j = 0 或s1[j] = s1[i - 1]。
此时next[i] 等于j + 1。
由于next 是最长公共前后缀,因此在j 的移动过程中一定会经过next[i] - 1 的位置。
void getnx()
{
nx[]=;
for(int i=,j=;i<=n;)
{
nx[i]=j;
while(j&&s1[j]!=s1[i])j=nx[j];
j++,i++;
}
}
3.匹配
在匹配过程中,设在主串中匹配到位置i,模式串中匹配到位置j。
首先如果s2[i] = s1[j],当前位置匹配成功,此时可以把i 和j 同时移动到下一个位置。
否则发生失配,需要进行调整,我们将j 置为next[j],然后继续匹配。
同样由于next 是最长公共前后缀,因此在j 的移动过程中不会跳过可能匹配的位置。
并且模式串中j 之前的部分一定可以匹配。
void kmp()
{
for(int i=,j=;i<=m;)
{
while(j&&s1[j]!=s2[i])j=nx[j];
if(j==n)
{
// 此时找到了一个能够匹配的位置
j=nx[j];
}
else j++,i++;
}
}
可以发现两部分代码有很大相似之处。
其实可以把求next 数组过程看做用模式串与自身匹配的过程。
4.时间复杂度
在求next 的过程中,j 指针每向后移动一步,i 指针就会向后移动一步。
而j 指针每延next 移动一次,就会向前移动大于等于一步。
由于i 指针会向后移动O(n) 次,因此j 指针也只会向后移动O(n) 次,因此向前同样最多移动O(n) 次。
因此求next 数组部分复杂度为O(n)。
与之类似,可以得出匹配过程的复杂度为O(m)。
因此KMP 算法的总复杂度为O(n + m)。
尾声:
总之,KMP算法是处理字符串匹配问题的一大利器。
搭配字符串上的DP可以说是......咳咳......很有趣......
(下篇高能预告)
KMP算法 详解+模板的更多相关文章
- KMP算法详解&&P3375 【模板】KMP字符串匹配题解
KMP算法详解: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt(雾)提出的. 对于字符串匹配问题(such as 问你在abababb中有多少个 ...
- kmp算法详解
转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...
- [转] KMP算法详解
转载自:http://www.matrix67.com/blog/archives/115 KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的K ...
- KMP算法详解(转自中学生OI写的。。ORZ!)
KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的KMP不是拿来放电影的(虽然我很喜欢这个软件),而是一种算法.KMP算法是拿来处理字符串匹配的.换句 ...
- 算法进阶面试题01——KMP算法详解、输出含两次原子串的最短串、判断T1是否包含T2子树、Manacher算法详解、使字符串成为最短回文串
1.KMP算法详解与应用 子序列:可以连续可以不连续. 子数组/串:要连续 暴力方法:逐个位置比对. KMP:让前面的,指导后面. 概念建设: d的最长前缀与最长后缀的匹配长度为3.(前缀不能到最后一 ...
- 数据结构4.3_字符串模式匹配——KMP算法详解
next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...
- 字符串匹配KMP算法详解
1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有比较详细的通俗易懂的讲解,另一方面也怪自己没有沉下心来研究.最近在leetcode上又遇见字符串匹配的题目,以此 ...
- KMP算法详解-彻底清楚了(转载+部分原创)
引言 KMP算法指的是字符串模式匹配算法,问题是:在主串T中找到第一次出现完整子串P时的起始位置.该算法是三位大牛:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,以其名字首字 ...
- 拓展KMP算法详解
拓展KMP解决的问题是给两个串S和T,长度分别是n和m,求S的每一个后缀子串与T的最长公共前缀分别是多少,记作extend数组,也就是说extend[i]表示S[i,n-1](i从0开始)和T的最长公 ...
随机推荐
- 游戏引擎UE4详解!
UE4 的全名是 Unreal Engine 4,中文译为“虚幻引擎4”.UE4 是一款由 Epic Games 公司开发的开源.商业收费.学习免费的游戏引擎.那你了解UE4吗?如果还不清楚,就一起来 ...
- 哈希表hashTable的Java设计
1:哈希表的概念 2:设计原理 3:哈希表的Java设计
- MySQL性能管理及架构设计:第1章 实例和故事
1-1 什么决定了电商双11大促的成败 数据库架构 1-2 在双11大促中的数据库服务器 通过监控信息从而确定:哪些因素影响了数据库性能? 1-3 在大促中什么影响了数据库性能 1-4 大表带来的问题 ...
- HDU 2094产生冠军(set思维题)
Problem Description 有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛.球赛的规则如下:如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能 ...
- 201771010123汪慧和《面向对象程序设计Java》第十一周实验总结
一.理论部分 1.栈 (1)栈是一种特殊的线性表,是一种后进先出的结构.(2)栈是限定仅在表尾进行插入和删除运算的线性表,表尾称为栈顶,表头称为栈底.(3)栈的物理存储可以用顺序存储结构,也可以用链式 ...
- linux环境java程序cpu爆表问题查证
1.top命令查找导致cup爆表的进程 2. top -H -p10832 (10832是Java进程的PID)命令找出了具体的线程 3.使用用命令 jstack 10832> jstack.t ...
- Go-并发和并行-协程-信道-缓冲信道-select-mutex-读写文件-beego框架
并发 Go 是并发式语言,而不是并行式语言.在讨论 Go 如何处理并发之前,我们必须理解何为并发,以及并发与并行的区别. 并发是什么? 并发是指立即处理多个任务的能力.一个CPU的情况下<意指看 ...
- [转载]matlab视频读取函数VideoReader
看到以前matlab中读取视频多 使用mmreader等(参考<matlab读取/播放视频的函数>),而现在matlab有一个专门的视频读取类VideoReader完成视频读取的功能. 相 ...
- Nginx安全优化
一.隐藏版本号 http { server_tokens off; } 经常会有针对某个版本的nginx安全漏洞出现,隐藏nginx版本号就成了主要的安全优化手段之一,当然最重要的是及时升级修复漏洞. ...
- 单机版solr的搭建
1.1. Solr的环境 Solr是java开发. 需要安装jdk. 安装环境Linux. 需要安装Tomcat. 1.2. 搭建步骤 第一步:把solr 的压缩包上传到Linux系统 第二步:解压s ...