杭电ACM——1075,What Are You Talking About(Tire树)

本文介绍了一种使用字典树解决火星文翻译问题的方法,通过构建特殊节点属性存储单词及其翻译状态,实现了对关键字及其前缀的有效处理。文章详细讲解了字典树的插入和查询操作,并提供了一个完整的C++实现示例。

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

字典树节点属性:存储单词。
注意!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
受网友友好提醒,这道题有可能会出现一下情况:

START
from fiwo
hello difh
trap dif
mars riwosf
earth fnnvk
like fiiwj
END
START
difh, i’m fiwo riwosf.
i fiiwj fnnvk! dif fnn
END

1、即某个关键字是另一个关键字的前缀的
2、以某个关键字的前缀出现,但是字典里不是一个关键字的,如上面的fnn是fnnvk的前缀

蓝瘦,因为考虑少这两种情况WA了好几遍。
那么为了解决这种情况,节点属性应设为一个结构体
struct nod
{
char s[50];
int flag;
}num[maxn];
同时记录单词,以及是否某个火星文在这里有翻译,flag=1有,flag=0无。
代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cctype>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
int Trie[maxn][26];
char s1[15],s2[15],s[3005],s0[3005],ans[8000][3005];
int tot=1,row=0,col=0;
struct nod
{
	char s[50];
	int flag;
}num[maxn];
void insert()
{
	int len,node,i,j;
	len=strlen(s2)-1;node=0;
	for(i=0;i<=len;i++)
	{
		if(Trie[node][s2[i]-'a']==0)
			Trie[node][s2[i]-'a']=tot++;
		node=Trie[node][s2[i]-'a'];
	}
	//strcpy(num[node],s1);cout<<num[node]<<endl;
	len=strlen(s1)-1;
	for(i=0;i<=len;i++)
		num[node].s[i]=s1[i];
	num[node].s[i]='\0';
	num[node].flag=1; 
}
int inquire()
{
	int len,node,i,j;
	len=strlen(s0)-1;node=0;
	for(i=0;i<=len;i++)
	{
		if(Trie[node][s0[i]-'a']==0)
			return -1;
		node=Trie[node][s0[i]-'a'];
	}
	if(num[node].flag==1)
		return node;
	else return -1;
}
void cp(char *str)
{
	int len,i;
	len=strlen(str)-1;
	for(i=0;i<=len;i++)
		ans[row][col++]=str[i];
//	cout<<str<<endl;
}
int main()
{
	char start[10]="START",end[10]="END";
	int i,j,len,flag,last,k,node;
	char c;
	while(~scanf("%s",s1))
	{
		if(strcmp(s1,start)==0)
			continue;
		else if(strcmp(s1,end)==0)
			break;
		else
		{
			scanf("%s",s2);
			insert();
		}
	}getchar();
	row=col=0;
	while(gets(s))			//要用gets
	{
		if(strcmp(s,start)==0)
			continue;
		else if(strcmp(s,end)==0)
			break;
		else
		{
			len=strlen(s)-1;last=j=0;
			for(i=0;i<=len;i++)
			{
				if(isalpha(s[i]))
					s0[j++]=s[i];
				else
				{
					if(j!=0)
					{
						s0[j]='\0';
						node=inquire();
						if(node==-1)
							cp(s0);
						else cp(num[node].s);
						if(i==len)	last=1;
						j=0;
					}
					ans[row][col++]=s[i];
				}
			}
			if(!last)
			{
				s0[j]='\0';
				node=inquire();
				if(node==-1)
					cp(s0);
				else cp(num[node].s);
				j=0;
			}
			ans[row][col]='\0';
			row++;col=0;
		}
	}
	for(i=0;i<=row-1;i++)
		printf("%s\n",ans[i]);
	return 0;
}

另外这道题也要注意下苛刻的输入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值