扩展KMP模板

概述

参考资料:

刘雅琼PPT讲解
kuangbin的博客

给出模板串A和子串B,长度分别为lenAlenA和lenBlenB,要求在线性时间内,对于每个A[i]A[i](0<=i<lenA)(0<=i<lenA)

求出A[i..lenA−1]A[i..lenA−1] 与B的最长公共前缀长度,记为ex[i]ex[i](或者说,ex[i]ex[i]为满足A[i..i+z−1]==B[0..z−1]A[i..i+z−1]==B[0..z−1]的最大的z值)。

扩展KMP可以用来解决很多字符串问题,如求一个字符串的最长回文子串和最长重复子串。

(1)头文件

1 #include <bits/stdc++.h>
2 using namespace std;
3 const int MAXN = 2000010;
4 int Next[MAXN];
5 int extend[MAXN];

(2)EXKMP

 1 void EKMP(char s[],char t[])//s为主串,t为模板串
 2 {
 3     int i,j,p,L;
 4     int slen = strlen(s);
 5     int tlen = strlen(t);
 6     Next[0] = tlen;
 7     j = 0;
 8     while(j+1 < tlen && t[j] == t[j+1])
 9         j++;
10     Next[1] = j;
11 
12     int a = 1;
13     for(i = 2;i < tlen;i++)
14     {
15         p = Next[a]+a-1;
16         L = Next[i-a];
17         if(i+L<p+1)
18             Next[i]=L;
19         else
20         {
21             j=max(0,p-i+1);
22             while(i+j < tlen && t[i+j] == t[j])
23                 j++;
24             Next[i] = j;
25             a = i;
26         }
27     }
28 
29     j = 0;
30     while(j < slen && j < tlen && s[j] == t[j])j++;
31     extend[0] = j;
32     a = 0;
33     for(i = 1;i < slen;i++)
34     {
35         p = extend[a]+a-1;
36         L = Next[i-a];
37         if(L+i < p+1)
38             extend[i] = L;
39         else
40         {
41             j = max(0,p-i+1);
42             while(i+j<slen && j < tlen && s[i+j] == t[j])
43                 j++;
44             extend[i] = j;
45             a = i;
46         }
47     }
48 }

补充

  • extend[i]extend[i]表示原串以第ii开始与模式串的前缀的最长匹配

经典题目:

HDU3613

HDU 3613 Best Reward(扩展KMP:回文判断) - CSDN博客

 

 

上一篇:浅入 ABP 系列(4):事件总线


下一篇:Springboot应用-具有Security特性的RestTemplate