trie-最短前缀问题

字符串的前缀是从给定字符串开头开始的子字符串。“碳"的前缀是:“c”,“ca”,“汽车”,“碳水化合物”,“碳水化合物"和"碳”。请注意,在此问题中,空字符串不被视为前缀,但每个非空字符串都被视为其前缀。在日常语言中,我们倾向于用前缀缩写单词。例如,“碳水化合物"通常缩写为"碳水化合物”。在此问题中,给定一组单词,您将在每个单词中找到唯一标识它表示的单词的最短前缀。
在下面的示例输入中,“碳水化合物"可以缩写为"carboh”,但不能缩写为"carbo”(或任何较短的词),因为列表中有以"carbo"为首的其他
词。
精确匹配将覆盖前缀匹配
项。例如,前缀"car"与给定的单词"汽车"完全匹配。因此,人们不言地理解,"汽车"是"汽车"的缩写,而不是"车厢"或列表中以"汽车"开头的任何其他词。
输入
输入至少包含两行,但不超过 1000 行。每行包含一个单词,由 1 到 20 个小写字母组成。
输出
输出包含与输入相同的行数。输出的每一行都包含输入相应行中的单词,后跟一个空格,并且唯一(无歧义)标识该单词的最短前缀。
示例输入
carbohydrate
cart
carburetor
caramel
caribou
carbonic
cartilage
carbon
carriage
carton
car
carbonate
样品输出
carbohydrate carboh
cart cart
carburetor carbu
caramel cara
caribou cari
carbonic carboni
cartilage carti
carbon carbon
carriage carr
carton carto
car car
carbonate carbona

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int N=5050;
int son[N][26],cnt[N],idx;//cnt访问次数 son--第i个单词
char str[N][N];    //节点i编号为j的子节点ch[i][j]

void insert(char str[])
{
	int p=0;
	for(int i=0;str[i]!='\0';i++)
	{
		int u=str[i]-'a';
		if(son[p][u]==0)
			son[p][u]=++idx;
		p=son[p][u];
		cnt[p]++;
	}
}

void query(char str[])
{
	int p=0;
	for(int i=0;str[i]!='\0';i++)
	{
		putchar(str[i]);
		int u=str[i]-'a';
		if(cnt[son[p][u]]==1)
			return;
		p=son[p][u];
	}
}

int main()
{
	int tot=0;
	while(scanf("%s",str[tot])!=EOF)
	{
		insert(str[tot]);
		tot++;
	}

	for(int i=0;i<tot;i++)
	{
		printf("%s ",str[i]);
		
		query(str[i]);
		printf("\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值