HDOJ 4300 Clairewd’s message

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;
}


你可能感兴趣的:(c,算法,测试,table,扩展)