拓展KMP算法详解
来源:互联网 发布:太原市九鼎软件 编辑:程序博客网 时间:2024/06/05 00:42
算法描述:设字符串T,长度为n,字符串S,长度为m。在线性时间内求出T的每一个后缀所对应S的最长前缀。
假设T=“AAAAB”,S="AAAA"。
我们从第一位开始匹配,匹配结果存放到ext数组中。显然ext【0】=4,然后我们就去计算ext【1】,显然ext【1】=3。如果还是如同算ext【0】这样的方法去匹配ext【1】会造成信息的浪费,因为前面有的信息已经知道了,就不需要一个一个再去比对了。这里我们记S【1到lens-1的元素】为S1,发现S1与S是有公共前缀的,同样我们用next数组记录下这公共前缀,显然next【1】=3。所以从T【1】开始之后的next【1】(3)位的数字都是相同的,这样就不用从头开始比对。
下面用图来举一个新的栗子。
我用黑色方格代表已经匹配的元素,黑色单向箭头代表元素相等。红色箭头代表待匹配元素。
当我们匹配完第一个元素(下标0)的时候开始匹配第二个元素(下标1),发现ext【1】=2,这样的话可以直接从S串的2号元素开始匹配,原因正如之前所说。
基本原理就是这个样子。下面说一说具体如何实现拓展kmp算法
首先我们要引入两个新的变量,p,p0。表示p从p0开始最长的匹配位置(如果感到模糊请继续看下去)。与manacher类似,我们需要维护这个最长长度。下面通过几个图来讲解一下。
(1)如图所示,红色箭头代表p,蓝色箭头代表p0,绿色箭头代表待匹配位置,设next【绿色箭头】=3。然后就有了下面的匹配方式。由于前三个相同,我们直接匹配第四个,也就是绿色方格。但是绿色方格中的元素可能相等吗?答案是否定的。如果相等了,我们的next【绿色箭头】就不是3了,而是4。虽然方格中没有真正的元素,但是仍然可以推的出绿色方格中的元素是不可能相同的。
绿色部分如果匹配了,那么next【绿色箭头】就产生了矛盾,S中4,5号元素就会相等
这是绿色箭头指向的元素匹配位置小于蓝色箭头(p0)的情况,那么大于等于的情况会是怎么样呢?
(2)紧接着上一个栗子,如果next【绿色箭头】=4,绿色箭头+next【绿色箭头】刚刚好指向了蓝色箭头的位置,这时候应该向下一位置开始匹配,因为还没有搜索到那个位置,所以你并不知道是不是会匹配,如果匹配了,那么就更新p与p0,如此反复,ext数组就求解完毕,算法结束。
.
然后我去抄了一个模板
const int maxn=10086; //字符串长度最大值int next[maxn],ex[maxn]; //ex数组即为extend数组//预处理计算next数组void GETNEXT(char *str){ int i=0,j,po,len=strlen(str); next[0]=len;//初始化next[0] while(str[i]==str[i+1]&&i+1<len)//计算next[1] i++; next[1]=i; po=1;//初始化po的位置 for(i=2; i<len; i++) { if(next[i-po]+i<next[po]+po)//第一种情况,可以直接得到next[i]的值 next[i]=next[i-po]; else//第二种情况,要继续匹配才能得到next[i]的值 { j=next[po]+po-i; if(j<0)j=0;//如果i>po+next[po],则要从头开始匹配 while(i+j<len&&str[j]==str[j+i])//计算next[i] j++; next[i]=j; po=i;//更新po的位置 } }}//计算extend数组void EXKMP(char *s1,char *s2){ int i=0,j,po,len=strlen(s1),l2=strlen(s2); GETNEXT(s2);//计算子串的next数组 while(s1[i]==s2[i]&&i<l2&&i<len)//计算ex[0] i++; ex[0]=i; po=0;//初始化po的位置 for(i=1; i<len; i++) { if(next[i-po]+i<ex[po]+po)//第一种情况,直接可以得到ex[i]的值 ex[i]=next[i-po]; else//第二种情况,要继续匹配才能得到ex[i]的值 { j=ex[po]+po-i; if(j<0)j=0;//如果i>ex[po]+po则要从头开始匹配 while(i+j<len&&j<l2&&s1[j+i]==s2[j])//计算ex[i] j++; ex[i]=j; po=i;//更新po的位置 } }}
- 拓展KMP算法详解
- kmp算法及其拓展
- 拓展kmp算法总结
- 拓展KMP算法
- 拓展KMP算法
- 拓展kmp算法总结
- KMP (KMP+拓展KMP)算法总结
- KMP算法&拓展KMP算法模板
- 拓展KMP详解+(笔记)
- KMP算法详解 【KMP】
- 拓展欧几里得算法详解
- hdu 4333 Revolving Digits 拓展kmp算法
- 【拓展kmp】
- 拓展kmp
- 拓展KMP
- kmp&&拓展kmp
- KMP算法详解
- KMP算法详解
- selenium2.0关于python的常用函数
- PRU-ICSS EtherCAT slave package
- RxJava2.0中just操作符用法和源码分析(二)
- 206。Reverse Linked List
- 重定向和转发
- 拓展KMP算法详解
- 顺序表的基本算法
- redis 服务器初始化
- 231.Power of Two
- BSP文件copy到linux源生目录下并解压
- 服务器中Windows 平台安装 MongoDB
- JS翻转效果
- PAT-A 1003. Emergency (25)
- jquery异步请求ajax()之dataType参数讲解