#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 100080
int Next[maxn],Extend[maxn];//Extend[i]表示原串以第i开始与模式串的前缀的最长匹配
char str1[maxn],str2[maxn];
void EKMP(char * s,char * t)//s为主串,t为模板串
{
int i,j,p,l;
int len = strlen(t);//len是模板串长度
int len1 = strlen(s);//len1是主串长度
memset(Next,0,sizeof(Next));
memset(Extend,0,sizeof(Extend));
Next[0] = len;
j = 0;
while(1+j < len && t[j] == t[1+j])j++;
Next[1] = j;
int a = 1;
for(i = 2;i < len;i++)
{
p = Next[a] + a - 1;
l = Next[i-a];
if(i+l < p+1) Next[i] = l;
else
{
j = max(0,p-i+1);
while(i+j<len && t[i+j]==t[0+j])j++;
Next[i] = j;
a = i;
}
}
j = 0;
while(j < len1 && j < len && s[j] == t[j]) j++;
Extend[0] = j;
a = 0;
for(i = 1;i < len1;i++)
{
p = Extend[a] + a - 1;
l = Next[i-a];
if(l+i < p+1) Extend[i] = Next[i-a];
else
{
j = max(0,p-i+1);
while(i+j < len1 && j < len && s[i+j] == t[j])j++;
Extend[i] = j;
a = i;
}
}
}
int main()
{
while(scanf("%s%s",str1,str2)==2)
{
EKMP(str1,str2);//str1是主串
int len1 = strlen(str1),len2 = strlen(str2);
for(int i = 0;i < len1;i++)
cout << Extend[i] << endl;
}
return 0;
}
EKMP模板
最新推荐文章于 2019-10-29 20:43:28 发布