扩展kmp                 LRH

所谓扩展kmp指的是与kmp相似的求辅助数组的原理,但是本身与kmp关系不大。

1.exkmp的用途:给定一个主串s和一个子串t,求出s中每一个后缀和子串t的最长公共前缀。

2.算法推导:

给定一个主串:S=aaaaaaaaaabaaa

 T=aaaaaaaaaaa

(下标都是从零开始!!!)

                 第一步

需要有两个辅助数组:extand[i]和next[i];

extand[i]:表示主串S以i开始的后缀与子串T的最长公共前缀。

next[i]:表示子串T中以i开始的后缀与子串本身的最长公共前缀。

首先看这个样例,很显然extend[1]=10。然后要求extend[2]。如果暴力求的话还要再用每个字符比较一遍太过麻烦。那么已经求得的extend[1]是不是可以利用呢?

通过求得的extend[1]我们已经知道了:S[1...10]=T[1…10](不知道为什么的看定义去)。那么S[2..10]=T[2…10]。再算extend[2]时很明显extand[1]是没有用的,所以要从S[2]匹配。于是我们就要再引入一个数组next[i]。根据定义:

因为next[2]=9;

所以T[2…11]=T[1…10];

所以T[2…10]=T[1…9](都删去一个字符)

所以T[1…9]=S[2…10]

所以extand[2]就等于9啊!!!多么神奇啊!

第二步

求完extand[2]后就可以知道这种求法原理是一种递推的。那么下面我们抛开特殊来看一般

我们假设extand[1…k]已经求好(就像刚刚那个extand[1]已经求好一样)。并且,在以前匹配过程中在S当中所匹配到的最远位置是p。那么这个最远的位置是不是就是i+extand[i]-1?(当前位置+匹配长度-1=匹配到的末端位置),其中i=1…k。不妨取这个最远的位置所对应的i是a,很显然这个a是比p要小的。那么根据定义就可以推出           S[a…p]=T[1…p-a+1];

所以 S[k+1…p]=T[k+a+2…p-a+1](都删去一段字符)

我们再定义一个L,另L= extand[k-a+2](注意:这是定义的,不要老是纠结他究竟是为了什么,不然会很痛苦!!!这个会用到的。)

那么根据L就可以推导出:T[1…L]=T[k-a+2…k+L-a+1]

相信看到这里大多数人都已经懵逼了,那我们还是先回想一下next数组的定义,然后画个图就能懂了:

是不是已经懂了?这是next数组的一个性质,前面在推extand[2]的时候应经用了。

第三步

现在就出现了两种情况:

(一) k+L<p

图中红色的区域一定是相等的,即S[k+1…k+1+L]=T[1…L]

因为前面已经推导过T[1…L]=T[k-a+2…k+L-a+1](1)

并且S[k+1…p]=T[k+a+2…p-a+1](2)   p>k+L

所以(1)式的右端点在(2)式右端点的左边。

所以 多出来的那块=(p-a+1)-(k+L-a+1)

再用p-[(p-a+1)-(k+L-a+1)]+1=k+L+1!

所以就推出了S[k+1…k+L+1]=T[1…L]。

那么就可以知道蓝色的部分一定不会相等(因为L=extend[k-a+2]呀,如果相等的话那extend[k-a+2]不就等于L+1甚至更大了吗?)

为什么k+L不能=p?  因为小于p时p之前一定存在一个字符与T[L+1]不匹配(图中蓝色区域)。如果等于p,那就无法判断下一位是否不匹配了。

所以我们就得出了extend[k+1]=L,就求出来了!

(二) k+L>=p

明白了第一种,这种情况就比较通俗易懂啦!

上图的紫色部分是未知的,红色部分是已经匹配的。因为在计算extend[1…k]时达到的最远位置是p,所以p之后的的位置无法访问。那怎么办?问我??这还用说:暴力求啊!

从S[p+1]和T[p-k+1]开始匹配不就完啦?之后更新extend[a]+a和extend[k+1]+k+1的大小,后者的就更新最远位置p然后,,,就没有然后了!!!!

那么next数组怎么求呢?其实next数组就是一个以T为主串,T为字串的一个特殊的扩展kmp!用上文介绍的相同算法计算next数组即可。

唉!这就完了。写了整整一个晚上,因为下午刚学,连推公式带迷茫的痛苦了三个小时,终于完成了再附一个代码:

Return 0!!!!!

扩展kmp——原创的更多相关文章

  1. 扩展KMP算法

    一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所 ...

  2. 扩展KMP --- HDU 3613 Best Reward

    Best Reward Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3613 Mean: 给你一个字符串,每个字符都有一个权 ...

  3. KMP和扩展KMP

    文章网上太多这里提一下代码细节: KMP: scanf("%s\n",s); scanf("%s\n",t); int ls=strlen(s),lt=strl ...

  4. UVA5876 Writings on the Wall 扩展KMP

    扩展KMP的简单题. #include<stdio.h> #include<string.h> #define maxn 51010 char s[maxn],t[maxn]; ...

  5. hdu4333 扩展KMP

    慢慢研究可以发现,可以用扩展kmp来求.由于扩展kmp的next[]只有一部分,当前位子前面那部分和母串的后部分,所以可以将字符串复制接在后面一次. 先求如果next[]>0&& ...

  6. 扩展KMP

    刘雅琼论文 http://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html 论文讲的非常详细. 给定母串S,子串T,n=strlen(S),m=st ...

  7. HDU 3336 扩展kmp

    题目大意: 找到字符串中所有和前缀字符串相同的子串的个数 对于这种前缀的问题,通常通过扩展kmp来解决 其实吧这是我第一次做扩展kmp的题目,原来确实看过这个概念,今天突然做到,所以这个扩展kmp的模 ...

  8. acdream1116 Gao the string!(扩展KMP)

    今天是字符串填坑的一天,首先填的第一个坑是扩展KMP.总结一下KMP和扩展KMP的区别. 在这里s是主串,t是模式串. KMP可以求出的是以s[i]为结尾的串和 t前缀匹配的最长的长度.假如这个长度是 ...

  9. hdu 4333(扩展kmp)

    题意:就是给你一个数字,然后把最后一个数字放到最前面去,经过几次变换后又回到原数字,问在这些数字中,比原数字小的,相等的,大的分别有多少个.比如341-->134-->413-->3 ...

随机推荐

  1. (五)python的发展历史

    1989年,为了打发圣诞节假期,Guido开始写Python语言的编译器.Python这个名字,来自Guido所挚爱的电视剧Monty Python's Flying Circus.他希望这个新的叫做 ...

  2. 主成分分析 R语言

    主成分分析(Principal Component Analysis,PCA), 是一种统计方法.通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分. 原理: ...

  3. [MFC美化] SkinMagic使用详解1- SkinMagic使用流程

    [SkinMagic使用流程] 1.工程配置SkinMagic相关文件 2.初始化SkinMagic皮肤文件,窗体加载皮肤 3.释放皮肤资源 特别声明,SkinMagic要是破解版的,如果不是,可能需 ...

  4. Ubuntu14.04安装PHP5

    因为任务需要在Ubuntu14.04的server版本下安装PHP5,所以总结一下   使用root进行安装  要么在前面加上sudo进行安装. apt-get install php5-cgi ap ...

  5. 约瑟夫问题-Josephus--及实例说明

    //---我保证所有的代码都已经通过测试---// 类似约瑟夫的问题又称为约瑟夫环.又称“丢手绢问题”. 这个问题来自于这样的一个关于著名犹太历史学家 Josephus传说: 在罗马人占领乔塔帕特后, ...

  6. Xsser

    来源:https://www.cqhacker.cn/post-174.html   XSSer使用说明 =============================================== ...

  7. WinForm 布局,容器、打印和对话框控件

    今天,我主要学习了容器控件.打印控件.对话框控件. 在正式进行今天的内容之前,首先补充了布局的两个属性:Anchor:锁定位置,Dock:填充位置,一般与容器控件配合使用. 之后,我学习了第一部分内容 ...

  8. NDEF消息解析实例[转]

      问题:按照NDEF消息格式来解析下列Hex串? D1 02 1F 53 70 91 01 0E 54 02  65 6E 68 65 6C 6C 6F 20 77 6F  72 6C 64 51 ...

  9. mysql备份和还原

    MySQLl提供了一个mysqldump命令,我们可以用它进行数据备份. 按提示输入密码,这就把abc数据库所有的表结构和数据备份到abc_20161108.sql了, # mysqldump -u ...

  10. CreateProcess函数诡异的表现

    场景:程序A使用CreateProcess函数去启动另一个程序(.exe)文件,在绝大部分情况下是可以成功启动的,但是在某些电脑上无效. 因为这“某些电脑”实在不好找,终于有一天借到一台这样的电脑. ...