Shortest Prefixes POJ - 2001(字典树)

字符串前缀是从给定字符串开始的子字符串。“carbon”的前缀是“c”、“ca”、“car”、“carb”、“carbo”和“carbon”。注意,在这个问题中,空字符串不被视为前缀,但每个非空字符串都被视为其自身的前缀。在日常语言中,我们倾向于用前缀来缩写单词。例如,“碳水化合物”通常缩写为“碳水化合物”。在这个问题中,给定一组单词,您将为每个单词找到唯一标识其所代表单词的最短前缀。              在下面的样本输入中,“碳水化合物”可以缩写为“carboh”,但不能缩写为“carbo”(或任何更短的词),因为列表中还有其他单词以“carbo”开头。              

完全匹配将覆盖前缀匹配。例如,前缀“car”与给定的单词“car”完全匹配。因此,可以毫不含糊地理解,“car”是“car”的缩写,而不是“carriage”或列表中以“car”开头的任何其他单词。              

输入              

输入至少包含两行,但不超过1000行。每行包含一个由1到20个小写字母组成的单词。              

输出              

输出包含与输入相同的行数。输出的每一行包含来自输入的相应行的单词,后跟一个空格,以及唯一(无歧义)标识该单词的最短前缀。 

Sample Input

carbohydrate
cart
carburetor
caramel
caribou
carbonic
cartilage
carbon
carriage
carton
car
carbonate

Sample Output

carbohydrate carboh
cart cart
carburetor carbu
caramel cara
caribou cari
carbonic carboni
cartilage carti
carbon carbon
carriage carr
carton carto
car car
carbonate carbona

看到题目 ,一开始不知道该怎么做,题目的意思是找到那个唯一的最短的前缀。看到大神的代码,就是字典序,将插入的字符串前缀都记一下数,最后再找那个数量为1的前缀(题目已经确保肯定会有一个答案)。最后题目要求是最短的前缀,我们就可以从一个串的一开始串起来,这样就是最短的了。

#include<iostream>
#include<cstdio>
#include<map>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
#include<vector>

#include<sstream> 
#define tle ios::sync_with_stdio(0),cin.tie(0)
using namespace std;
const int maxn=1000000;
typedef long long ll;
typedef pair<int,int> p;
char s[maxn][25];

int tree[maxn][30];
int k=0;
int sum[maxn];


void insert(string s)
{
	int root=0;
	
	for(int i=0;i<s.length();i++)
	{
		int x=s[i]-'0';
		if(!tree[root][x])
			tree[root][x]=++k;			
		sum[ tree[root][x] ]++;
		root=tree[root][x];
	}
	
	
	
}


string find(string t)
{
	int root=0;
	string str;
	
	for(int i=0;i<t.length();i++)
	{
		int x=t[i]-'0';
		root=tree[root][x];
		str+=t[i];
		if(sum[root]==1)
			return str;
		
		
	}
	
	
}





int main()
{
	tle;
	
	int num=0;
	while(scanf("%s",s[num])!=EOF)
	{
		insert(s[num]);
		
		num++;
	}
	
	for(int i=0;i<num;i++)
	{
		//cout<<s[i]<<' '<<find(s[i])<<endl;
		printf("%s %s\n",s[i],find(s[i]).c_str());
		
	}
	
	return 0;
}

 找到那个出现一次的最短前缀字符串。模板

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值