扩展KMP算法

扩展KMP,用于求s的后缀的最长前缀。用extand数组表示第i个后缀的最长前缀的字符个数。

注意几点:1.next数组是对T的

       2.extand数组是对S的

     3.应用:回文,重复串等

代码如下:

 1 #include<iostream>
 2 #include<string>
 3 #include<cstdio>
 4 using namespace std;
 5 const int MM=100005;  //长度最大值
 6 int next[MM],extand[MM];
 7 char S[MM],T[MM];
 8 void GetNext(const char *T){
 9      int len=strlen(T),a=0;
10      next[0]=len;
11      while(a<len-1 && T[a]==T[a+1]) a++;
12      next[1]=a;
13      a=1;
14      for(int k=2;k<len;k++){
15          int p=a+next[a]-1,L=next[k-a];
16          if( (k-1)+L >= p){
17              int j = (p-k+1)>0 ? (p-k+1) : 0;
18              while(k+j<len && T[k+j]==T[j]) j++;
19              next[k]=j;
20              a=k;
21          }
22          else
23              next[k]=L;
24      }
25 }
26 void GetExtand(const char *S,const char *T){
27      GetNext(T);
28      int slen=strlen(S),tlen=strlen(T),a=0;
29      int MinLen = slen < tlen ? slen : tlen;
30      while(a<MinLen && S[a]==T[a]) a++;
31      extand[0]=a;
32      a=0;
33      for(int k=1;k<slen;k++){
34          int p=a+extand[a]-1, L=next[k-a];
35          if( (k-1)+L >= p){
36              int j= (p-k+1) > 0 ? (p-k+1) : 0;
37              while(k+j<slen && j<tlen && S[k+j]==T[j]) j++;
38              extand[k]=j;
39              a=k;
40          }
41          else
42              extand[k]=L;
43      }
44 }
45 int main(){
46     while(scanf("%s%s",S,T)==2){
47          GetExtand(S,T);
48          for(int i=0;i<strlen(T);i++)
49              printf("%d ",next[i]);
50          puts("");
51          for(int i=0;i<strlen(S);i++)
52              printf("%d ",extand[i]);
53          puts("");
54     }
55     return 0;
56 }  

时间: 2024-11-20 14:14:20

扩展KMP算法的相关文章

扩展KMP算法小记

参考来自<拓展kmp算法总结>:http://blog.csdn.net/dyx404514/article/details/41831947 扩展KMP解决的问题: 定义母串S和子串T,S的长度为n,T的长度为m: 求  字符串T  与  字符串S的每一个后缀  的最长公共前缀: 也就是说,设有extend数组:extend[i]表示T与S[i,n-1]的最长公共前缀,要求出所有extend[i](0<=i<n). (注意到,如果存在若干个extend[i]=m,则表示T在S中完

(模板)扩展kmp算法(luoguP5410)

题目链接:https://www.luogu.org/problem/P5410 题意:有两个字符串a,b,要求输出b与a的每一个后缀的最长公共前缀.输出: 第一行有lenb个数,为b的next数组(特别地,next1为lenb) 第二行有lena个数,即答案. 思路:扩展kmp模板,涉及字典树,后续再补,先放模板. AC code: #include<bits/stdc++.h> #define N 1000010 using namespace std; int q,nxt[N],exte

浅谈Manacher算法与扩展KMP之间的联系

首先,在谈到Manacher算法之前,我们先来看一个小问题:给定一个字符串S,求该字符串的最长回文子串的长度.对于该问题的求解,网上解法颇多,时间复杂度也不尽相同,这里列述几种常见的解法. 解法一 通过枚举S的子串,然后判断该子串是否为回文,由于S的子串个数大约为,加上每次判断需要的时间,所以总的时间复杂度为,空间复杂度为. bool check(string &S, int left, int right) { while (left < right && S[left]

拓展kmp算法总结

算法总结第二弹,上次总结了下kmp,这次就来拓展kmp吧. 拓展kmp是对KMP算法的扩展,它解决如下问题: 定义母串S,和字串T,设S的长度为n,T的长度为m,求T与S的每一个后缀的最长公共前缀,也就是说,设extend数组,extend[i]表示T与S[i,n-1]的最长公共前缀,要求出所有extend[i](0<=i<n). 注意到,如果有一个位置extend[i]=m,则表示T在S中出现,而且是在位置i出现,这就是标准的KMP问题,所以说拓展kmp是对KMP算法的扩展,所以一般将它称为

数据结构--KMP算法总结

数据结构—KMP KMP算法用于解决两个字符串匹配的问题,但更多的时候用到的是next数组的含义,用到next数组的时候,大多是题目跟前后缀有关的 . 首先介绍KMP算法:(假定next数组已经学会,后边next数组会在介绍) 上图T为主链,P为模板链,要求P在T中是否出现,出现就返回位置. 朴素算法会顺序遍历,比较第一次的时候p[0]处失配,然后向后移动继续匹配.数据量大的时候这么做肯定是不可行的.所以这里就会有KMP算法!在一次失配之后,KMP算法认为这里已经失配了,就不能在比较一遍了,而是

扩展KMP --- HDU 3613 Best Reward

Best Reward Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3613 Mean: 给你一个字符串,每个字符都有一个权值(可能为负),让你将这个字符串分成两个字串,使得这两个子串的价值之和最大.一个子串价值的计算方法:如果这个子串是回文串,那么价值就是这个子串所有字符权值之和:否则价值为0. analyse: 经典的扩展KMP算法运用. 假设输入串为s,那么我们首先:strcpy(s1,s)     ;      

扩展KMP,附上例题(HDU - 4333 Revolving Digits)

给出模板串S和串T,长度分别为Slen和Tlen,在线性时间内,对于每个S[i](0<=i<Slen),求出S[i..Slen-1]与T的 最长公共前缀长度,记为extend[i],extend[i]存放s[i]开始与T的最长公共前缀长度. 例子 a a a a a a a b b b a a a a a c extend 5 4 3 2 1 0 0 0 0 0 HDU - 4333 Revolving Digits Time Limit: 3000/1000 MS (Java/Others)

KMP、扩展KMP、MANACHER

一.KMP 作用:用于在一个文本串S内查找一个模式串P出现的位置 string str = "bacbababadababacambabacaddababacasdsd"; string ptr = "ababaca"; 如上图,可得在第10与26处包含ptr数组: 暴力做法:暴力for,碰到不一样的直接返回,从后一个开始继续for,最差能到O(n * m) KMP 做法: 主要的思路是跳,比如你一开始从上面例子里的bacbababadababacambabacad

8.2 kmp 扩展kmp

假设一母串S,子串P KMP:用于求解子串P在母串S中第一次出现的位置,或是在母串S中出现的次数.(最长公共前缀后缀) next数组的含义:next[i]表示前面长度为i的子串中,前缀和后缀相等的最大长度. 拓展kmp是对KMP算法的扩展,它解决如下问题:(最长公共前缀) 定义母串S,和子串T,设S的长度为n,T的长度为m,求T与S的每一个后缀的最长公共前缀,也就是说,设extend数组,extend[i]表示T与S[i,n-1]的最长公共前缀,要求出所有extend[i](0<=i<n).