什么是KMP算法?KMP算法推导

花了大概3天时间,了解,理解,推理KMP算法,这里做一次总结!希望能给看到的人带来帮助!!

1.什么是KMP算法?

在主串Str中查找模式串Pattern的方法中,有一种方式叫KMP算法

KMP算法是在模式串字符与主串字符匹配失配时,利用已经匹配的模式串字符子集的最大块对称性,让模式串尽量后移的算法。

这里有3个概念:失配,已经匹配的模式串子集,块对称性

失配和隐含信息

在模式串的字符与主串字符比较的过程中,字符相等就是匹配,字符不等就是失配;

隐含信息是,失配之前,都是匹配。

在主串S[0,100]中查找模式串P[0,6],从下标0开始查找,在下标为5的位置失配,记为P[0,5]失配,则有

P[5]!=S[5],又有S[0,4]=P[0,4]

则P[0,4]都是匹配的!

已经匹配的模式串子集

接上一例,模式串是P[0,6],而P[0,4]都是匹配的,所以,已经匹配的模式串子集有

Pcs={ P[0,4],P[0,3],P[0,2],P[0,1],P[0] }

2.块对称性

什么是块对称性?

块对称性,就是字符串前缀,后缀重叠;

比如: a b c d a b c

前缀:除了最后一个字母外,所有的前缀子集;

如: a,ab,abc,abcd,abcda,abcdab

后缀:除了第一个字母外,所有的后缀子集

如: bcdabc,cdabc,dabc,abc,bc,c

这里前缀abc和后缀abc重合

可以把这个重合看做,相对于绿块对称,所以叫它块对称性

块对称有很多种;比如:

咦?大家都在一水平排,怎么有一个飞起来了?

飞起来那个将在利用最大快对称性 小节讲解。

块有什么特点?

特点:拥有块对称性的字符串至少有2块对称重合的的部分;

分析,对称是修饰,重合是关键。而且重合的是前缀和后缀。

如何利用块对称性?

模式串如图,如果模式串和主串Str匹配的过程中,在l这失配即P[0,7]失配,你会怎样?

分析,

第一,模式串的P[0,6]和主串放入S[0,6]是完全匹配的

第二,P[0,6]串是块对称的!

因为P[0,6]刚好有块对称性,我可以把前缀abc移动到后缀abc的位置,然后让d与主串去匹配,这样就利用快对称性了对吧?

总结,可以在P[7]失配时,看失配字符的最大前缀P[0,6]是否有块对称性,如果有,我们就可以向右移动模式串,让左边的重合前缀移动到右边的重合后缀,再让模式串和主串比较!

利用最大块对称性?什么意思?

什么是KMP算法小节里,说KMP是在模式串与主串匹配失配时,利用已经匹配的模式串子集的最大块对称性,尽量让模式串右移!这里的利用最大块对称性是什么意思?

这里利用最大块对称性意味着可能发生递归!

把上个案例的d换成k,如下图:

KMP算法会预先计算出模式串所有前缀子集中哪些前缀有块对称性,在这些有块对称性的前缀的后一个字符失配时,利用其块对称性;

比如本例中P[0,6]有块对称性,那么在P[0,7]也就是l失配时,

会先利用P[0,6]的块对称性,即P[0,2]和P[4,6]相遇于字符P[3]块对称,

如果不行,会看P[0,2]块对称重合的部分有没有块对称性,

有,就利用;以此类推,一直递归到没有块对称性为止。

块对称长度的意义-编程

第一次移动中,3是什么?块对称重合长度,也是下次开始比较的位置!

第二次移动中,1是什么?块对称重合长度,也是下次开始比较的位置!

3.next数组推导-计算块对称性

单独的块对称性是没有意义的,块对称性必须结合上失配,才能利用块对称性!

所以,应该计算出Pattern所有前缀子集失配时的块对称性!放到一个叫next[]数组的地方!

如何计算呢?

next数组是计算失配时的块对称性,

当第1个字符失配时,压根就没有前缀后缀的说法,所以有next[0]是不存在块对称性的,记为next[0]=-1;

当第2个字符失配时,它的子集只有1个字符,也是没有前缀后缀,没有块对称性,所以记为next[1]=0;

再看图,对于值k,已有p0 p1, ..., pk-1 = pj-k pj-k+1, ..., pj-1,则有next[j] = k。

next[j] = k代表了什么呢?

代表在Pj之前,有长度为k的块对称性,有2个长度为k的重合部分。

总结一下,前提条件如下:

条件1.next[0]是不存在的,next[1]=0

条件2.对于下标值k,已有p0 p1, ..., pk-1 = pj-k pj-k+1, ..., pj-1,则有next[j] = k

next[]数组是从0开始被初始的,如果我们能推导出next[j+1] = 什么,是不是就可以计算出next[]数组? 是吧

下面来推导next[j+1]

已知:

p0 p1, ..., pk-1 = pj-k pj-k+1, ..., pj-1,==》 next[j] = k

如果pk与pj匹配

则有p0 p1, ..., pk-1,pk = pj-k pj-k+1, ..., pj-1pj,==》 next[j+1] = k+1;

原来有2个长度为k的对称重合部分,pk与pj匹配后,2个长度为k对称重合的部分又有了1对字符重合,所以有next[j+1]=k+1;

再看图,next[j]=k,当pj失配时,下一次用pk去和主串匹配;所以next[j]的实际意义是,当pj失配时,下一次应该用哪个字符去和主串匹配!!

条件3.next[ ]数组的值就是当次失配时,下一次匹配的位置!

如果pk与pj不匹配,next[j+1]=?

next[j+1]的实际意义是,p[0,j+1]的pj+1失配时,p[0,j]的块对称重合长度,也是下一次匹配时应该用模式串的哪个字符与主串匹配,哪个字符的下标就是next[j+1]。

具体详参块对称长度的意义-编程

下一次用哪个字符比较呢?

设a1=p0 p1,...,pk-1,a2=pj-k pj-k+1,...,pj-1;a1==a2

当pk与pj不匹配时,不能用a1替换a2,如图绿叉;

因为a2是离与主串最近的部分,所以这时候应该分析a2是否有块对称性,

如果a2有块对称性,那么a1也有块对称性,如图绿框;

所以,这时应该分析p[0,k]的块对称性,也就是next[k]。

设x1与x2关于绿框对称;

x3与x4关于绿框对称;

那么把x1移动到x4的位置,是不是就可以最大利用上;

所以next[j+1]=next[k];

总结一下

If ( p[k] == p[j] )  next[j+1]=k+1

else next[k+1]= next[k]

4.参考文献

https://blog.csdn.net/v_july_v/article/details/7041827

http://www.codeceo.com/kmp-next-array.html

https://www.zhihu.com/question/21474082  next数组推导

https://blog.csdn.net/yearn520/article/details/6729426 next数组推到原则

https://www.xahkbg.com/

KMP中,计算目标查询串T的next[]数组是关键;

https://zhuanlan.zhihu.com/p/24274982

https://blog.csdn.net/yearn520/article/details/6729426

http://www.cnblogs.com/c-cloud/p/3224788.html

https://zhuanlan.zhihu.com/p/24649304

原文地址:https://www.cnblogs.com/imxiangbei/p/8727536.html

时间: 2024-11-11 19:07:55

什么是KMP算法?KMP算法推导的相关文章

[C++] [算法] KMP算法

在虚拟机上测评了下MySQL 和 PostgreSQL 的各种LOAD FILE方式以及时间. 因为是虚拟机上的测评,所以时间只做参考,不要太较真, 看看就好了.MySQL 工具:    1. 自带mysqlimport工具.    2. 命令行 load data infile ...    3. 利用mysql-connector-python Driver来写的脚本. PostgreSQL 工具:    1. pgloader 第三方工具.    2. 命令行 copy ... from

KMP及其改进算法

本文主要讲述KMP已经KMP的一种改进方法.若发现不正确的地方,欢迎交流指出,谢谢! KMP算法的基本思想: KMP的算法流程: 每当一趟匹配过程中出现字符比较不等时,不需回溯 i 指针,而是利用已经得到的部分匹配的结果将模式向右滑动尽可能远的一段距离后,继续进行比较. 设S为目标串,T为模式串,设 i 指针和 j 指针分别指示目标串和模式串中正待比较的字符. 开始时,令i=0,j=0.如果Si==Tj,则使i和j的值分别增加l:反之,i不变,j的值退回到j=next[j]的位置(即模式串右滑)

字符串查找算法-KMP

/** *    KMP algorithm is a famous way to find a substring from a text. To understand its' capacity, we should acquaint onself with the normal algorithm. */ /** *    simple algorithm * *    workflow: *        (say,  @ct means for currently position o

菜鸟学算法-KMP算法

一. KMP算法 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,简称KMP算法.KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息. 二. KMP算法的意义 先举一个简单模式匹配的例子,给定字符串T=“abababca”,S=“bacbababaabcbab”,判断T是否是S的子串,如果用暴力扫描的话,就是拿着T字符串从

关于两个字符串的kmp比对算法

关于两个字符串的kmp比对算法 假设有字符串X和Y,满足len(X)>len(Y),要比对这两个字符串. 我们知道,最朴实的方法,就是现将二者对齐,然后依次比对对应位置的字符.如果能匹配到Y最后位置,则匹配成功:如果匹配失败,则将Y右移一位,再从头进行匹配. 设字符串X为dababeabafdababcg:字符串Y为ababc. 这种比对方法如下所示: 起始时,二者对其,第一个字符不匹配 :| :dababeabafdababcg :ababc 右移一位,比对位置移动到Y起始位置 : | :da

KMP算法 KMP模式匹配 二(串)

B - KMP模式匹配 二(串) Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Description 输入一个主串和一个子串,用KMP进行匹配,问进行几趟匹配才成功,若没成功,则输出0 Input 输入一个主串和一个子串 Output 匹配的趟数 Sample Input ababcabcacbab abcac

KMP算法 KMP模式匹配 一(串)

A - KMP模式匹配 一(串) Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Description 求子串的next值,用next数组存放,全部输出 Input 输入一个字符串 Output 输出所有next值 Sample Input abaabcac Sample Output 0 1 1 2 2 3 1

POJ-1061 青蛙的约会-数论扩展欧几里德算法入门及推导

Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的.但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的.为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面. 我们把这

【转载】分布式系列文章——Paxos算法原理与推导

转载:http://linbingdong.com/2017/04/17/%E5%88%86%E5%B8%83%E5%BC%8F%E7%B3%BB%E5%88%97%E6%96%87%E7%AB%A0%E2%80%94%E2%80%94Paxos%E7%AE%97%E6%B3%95%E5%8E%9F%E7%90%86%E4%B8%8E%E6%8E%A8%E5%AF%BC/ Paxos算法在分布式领域具有非常重要的地位.但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难. 网上

【机器学习】算法原理详细推导与实现(五):支持向量机(下)

[机器学习]算法原理详细推导与实现(五):支持向量机(下) 上一章节介绍了支持向量机的生成和求解方式,能够根据训练集依次得出\(\omega\).\(b\)的计算方式,但是如何求解需要用到核函数,将在这一章详细推导实现. 核函数 在讲核函数之前,要对上一章节得到的结果列举出来.之前需要优化的凸函数为: \[ min_{\gamma,\omega,b}->\frac{1}{2}||\omega||^2 \] \[ y^{(i)}(\omega^Tx^{(i)}+b) \geq 1 ,i=1,2,.