码迷,mamicode.com
首页 > 其他好文 > 详细

扩展kmp--模板解析

时间:2015-05-24 14:08:06      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

扩展kmp:

  用于求串的各个后缀与原串的最长公共前缀的长度;

上图的是字符串自匹配的过程:

图一:

    假设现在匹配到i-1了,开始求next [ i ] 的值,此时,k记录的是到目前为止匹配到的最远的位置的那一次的起点,p标志的是已经匹配过的最远的点;

图二:

    因为前面是匹配过的,所以可以知道,k~p和源串的1~b是一模一样的,所以 i 匹配的前一段可以和k~p段直接匹配,而不用和源串匹配,如果i匹配完成后,从i开始next[ i ]长度是和源串一模一样的。这个时候可以看图三。

图三:

    可以看到 i 与 k 的相对位置和a 与 1 的相对位置是一样的,而且1~a与k~i之间的是一样的,i与a也是一样的,而且next[ a ]是已经计算过的,所以用l = next[ i - k ]

p=k+next[ k ];   然后  if ( l<p)就是当用之前的匹配结果没有匹配超出p那么就可以直接用之前的结果了:next[ i ]=l;如果超出了p的范围,就要把超出的部分匹配一下,然后要更新k;

这样自匹配就结束了;

然后是字符间匹配,过程几乎一模一样;不再详述;

代码如下;

技术分享
 1 /*
 2    扩展kmp,计算小串对于大串的每一个后缀的最大公共前缀;
 3    这里求a串关于b串的每个后缀的最长公共前缀;
 4    首先是a串自匹配;
 5    然后串间匹配;
 6  */
 7 #include<iostream>
 8 #include<cstdio>
 9 #include<cstring>
10 #include<string>
11 #include<algorithm>
12 using namespace std;
13 string a,b;
14 int next[10000]={0},ret[100000]={0};
15 int m,n;
16 void extended_kmp()
17 {
18     //next[]数组记录的是自匹配的长度;
19     //ret[]数组记录的是字符串之间匹配的长度;
20     //a是子串,b是长串;
21     int i,j,k;
22     for(j=0;j+1<m&&a[j]==a[j+1];j++);
23     next[1]=j;
24     k=1;                                          //k表示的是最远的匹配到的那一个子串的起点;
25     for(i=2;i<m;i++)
26     {
27         int p=k+next[k],l=next[i-k];            //len记录的是目前匹配到的最远的位置;
28         if(l<p-i)
29             next[i]=l;
30         else
31         {
32             for(j=max(0,len-i);i+j<m&&a[j]==a[i+j];j++);
33             next[i]=j;
34             k=i;
35         }
36     }
37     for(j=0;j<n&&j<m&&a[j]==b[j];j++);
38     ret[0]=j;
39     k=0;
40     for(i=1;i<n;i++)
41     {
42         int p=k+next[k],l=next[i-k];
43         if(l<p-i)
44             ret[i]=l;
45         else
46         {
47             for(j=max(0,len-i);j<m&&i+j<n&&a[j]==b[i+j];j++);
48             ret[i]=j;
49             k=i;
50         }
51     }
52 }
53 int main()
54 {
55     cin>>a>>b;
56     m=a.size();
57     n=b.size();
58     extended_kmp();
59     return 0;
60 }
View Code

 

扩展kmp--模板解析

标签:

原文地址:http://www.cnblogs.com/by-1075324834/p/4525743.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!