http://acm.hdu.edu.cn/showproblem.php?pid=4300
第一次搞KMP,比赛的时候现学现卖,代码写的不怎么好,仅供参考……不足之处,还望高人指点!
题意:截获了一段电文,电文至少含有密文(和明文),密文完整,明文可能不全甚至完全没有。现要求根据给出的匹配规则输出完整的电文(要求使电文最短)。
思路:使电文最短,即找到电文后半部分与前半部分的最大匹配。用扩展KMP算法找匹配。
因为密文长度肯定大于等于明文,所以从中间开始找即可。
因此主串比匹配串短,寻找匹配的停止条件为主串结束。
最后将不完成的部分补齐即可。
测试数据据说不强,用普通的KMP也能搞出来。
#include<stdio.h>
#include<string.h>
#define maxn 111111
int next[maxn],s,t;
char match[30],table[30];
void getnext(char T[])
{
int i,j;
i=0;next[0]=-1;j=-1;
while(i<t)
{
if(j==-1||T[i]==T[j])
{
i++;j++;
if(T[i]!=T[j])
next[i]=j;
else
next[i]=next[j];
}
else
j=next[j];
}
}
int kmp(char S[],char T[])
{
int i,j;
i=0;j=0;
while(i<s&&j<t)
{
if(j==-1||S[i]==table[T[j]-'a'])
{
i++;j++;
if(i==s)
return j;
}
else
j=next[j];
}
return 0;
}
int main()
{
int i,C,j;
char ip[maxn],S[maxn];
while(scanf("%d",&C)==1)
{
while(C--)
{
scanf("%s",match);
scanf("%s",ip);
strcpy(S,ip+(strlen(ip)+1)/2);
s=strlen(S);
t=strlen(ip);
for(i=0;match[i];i++)
table[match[i]-'a']='a'+i;
getnext(ip);
i=kmp(S,ip);
printf("%s",ip);
for(j=i;j<=t-i-1;j++)
printf("%c",table[ip[j]-'a']);
printf("\n");
}
}
return 0;
}