字符串前缀是从给定字符串开始的子字符串。“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;
}
找到那个出现一次的最短前缀字符串。模板