KMP
KMP是一种快速的字符串匹配算法,关键步骤是对每一个匹配串产生一个next数组。
void kmp_next(char *s)
{
int len = strlen(s);
next[0] = -1;
int k = -1;
for(int i = 1; i < len; i ++) {
while(k > -1 && s[k+1] != s[i]) {
k = next[k];
}
if(s[k+1] == s[i]) {
k ++;
}
next[i] = k;
}
}
Number Sequence
HDU - 1711
#include
#include
#include
#include
using namespace std;
const int MAXM=10500;
const int MAXN=1000500;
int n,m,t;
int nextc[MAXM];
int ori[MAXN];
int des[MAXM];
void findnext(){
int k=-1,j=0;
while(j
e-KMP
算法链接:https://subetter.com/algorith...
扩展KMP算法:给定两个字符串S和T(长度分别为n和m),下标从0开始,定义extend[i]等于S[i]...S[n-1]与T的最长相同前缀的长度,求出所有的extend[i]。
为获得extend数组,我们首先要构造一个辅助数组next,next[i]代表T[i:]和T[:]的最长公共子前缀。
/* 求解 T 中 next[],注释参考 GetExtend() */
void GetNext(string & T, int & m, int next[])
{
int a = 0, p = 0;
next[0] = m;
for (int i = 1; i < m; i++)
{
if (i >= p || i + next[i - a] >= p)
{
if (i >= p)
p = i;
while (p < m && T[p] == T[p - i])
p++;
next[i] = p - i;
a = i;
}
else
next[i] = next[i - a];
}
}
/* 求解 extend[] */
void GetExtend(string & S, int & n, string & T, int & m, int extend[], int next[])
{
int a = 0, p = 0;
GetNext(T, m, next);
for (int i = 0; i < n; i++)
{
if (i >= p || i + next[i - a] >= p) // i >= p 的作用:举个典型例子,S 和 T 无一字符相同
{
if (i >= p)
p = i;
while (p < n && p - i < m && S[p] == T[p - i])
p++;
extend[i] = p - i;
a = i;
}
else
extend[i] = next[i - a];
}
}
Simpsons’ Hidden Talents
HDU - 2594
本题既可以使用KMP又可以使用扩展KMP算法。
算法一:扩展KMP
//eKMP
#include
#include
#include
using namespace std;
const int MAXN=50050;
const int MAXM=50050;
int n,m;
char o[MAXN];
char d[MAXM];
int nexts[MAXM];
int extend[MAXN];
void getNext(){
int i=0,p=m,a=0;//p是之前所能匹配的最大位置,[a,p)是当前最大匹配,现在开始匹配i
nexts[0]=m;
if(m<1)
return;
p=1;
while(p=p||i+nexts[i-a]>=p)
{
if(i>=p)
p=i;
while(d[p]==d[p-i])
p++;
nexts[i]=p-i;
a=i;
}else{
nexts[i]=nexts[i-a];
}
}
}
void getExtend(){
int a = 0, p = 0;
getNext();
for (int i = 0; i < n; i++)
{
if (i >= p || i + nexts[i - a] >= p) // i >= p 的作用:举个典型例子,S 和 T 无一字符相同
{
if (i >= p)
p = i;
while (p < n && p - i < m && o[p] == d[p - i])
p++;
extend[i] = p - i;
a = i;
}
else
extend[i] = nexts[i - a];
}
}
int main(){
while(~scanf("%s%s",&d,&o)){
memset(nexts,0,sizeof(nexts));
memset(extend,0,sizeof(extend));
n=strlen(o);
m=strlen(d);
getExtend();
int ans=0;
for(int i=0;i
算法二:KMP
//KMP
#include
#include
#include
using namespace std;
const int MAXN=50050;
const int MAXM=50050;
int nexts[MAXN+MAXM];
char S[MAXN+MAXM];
char s1[MAXM];
int n;
void getNext(){
int k=-1,i=0;
nexts[i]=-1;
for(int i=1;i=0&&S[i]!=S[k+1])
k=nexts[k];
if(S[i]==S[k+1])
k=k+1;
}
nexts[i]=k;
}
}
int main(){
while(~scanf("%s%s",&S,&s1)){
strcat(S,"*");
strcat(S,s1);
n=strlen(S);
getNext();
int ans=nexts[n-1];
if(ans==-1)
printf("0\n");
else{
for(int i=0;i<=ans;i++){
printf("%c",S[i]);
}
printf(" %d\n",ans+1);
}
}
}