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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章