hdu4300 Clairewd’s message(KMP)

本文介绍了一种基于给定密码表的字符串匹配算法。通过将输入串分为密码与明码两部分,利用KMP算法原理实现密码模式串与明码转换后的密码串之间的匹配,从而完成字符串的最小补全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这题描述简直惊人。其实就是说先给你一个密码表。然后给你一个不一定完整的串。原串满足前一半是密码,后一半是明码。要求你最小的补全这个串。首先我们要明确:设给的串长度为len,则1...(len+1)/2的字母一定是密码。我们可以把这一部分作为模式串,去匹配后面的串。(当然因为我们假定后面的串都是明码,所以我们要把后面的串翻译成密码来匹配)。我们假设最后一位匹配到了模式串的第k位。则说明1..len-k都是密码。我们按此输出原串即可。注意别忘了加\0,害我WA了好久。打算一会再写个exkmp的补上。。

#include <cstdio>
#include <cstring>
#define N 100010
int tst,n,fail[N];
char a[255],b[255],s[N<<1],s2[N];
inline void getfail(int m){
	int k=0;fail[1]=0;
	for(int i=2;i<=m;++i){
		while(k&&s[k+1]!=s[i]) k=fail[k];
		if(s[k+1]==s[i]) ++k;
		fail[i]=k;
	}
}
int main(){
//	freopen("a.in","r",stdin);
	scanf("%d",&tst);
	while(tst--){
		n=0;
		scanf("%s%s",a+'a',s+1);int len=strlen(s+1);
		for(int i='a';i<='z';++i) b[a[i]]=i;
		for(int i=(len+1)/2+1;i<=len;++i) s2[++n]=a[s[i]];
		getfail((len+1)/2);int k=0;
		for(int i=1;i<=n;++i){
			while(k&&s[k+1]!=s2[i]) k=fail[k];
			if(s[k+1]==s2[i]) ++k;
		}int m=len;
		for(int i=k+1;i<=len-k;++i) s[++m]=b[s[i]];
		s[++m]=0;//别忘了加\0 
		puts(s+1);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值