trie树

xiaoxiao2025-10-21  17

Description

 

最近情报人员得到了一些经过加密的文章,每个单词都很长。破译人员想到先把单词简化一下,方法是把每个单词尽量取短些的前缀,但所取的前缀不能是其他单词的前缀。

这个任务现在就交给你来完成。

解释:“字符串s1是s2的前缀”是说把字符串s2的后面去掉某些,只保留与s1的长度时,s2就与s1完全相同。如:“abc”是“abcde”和“abc”的前缀,但不是“ababc”的前缀。

 


Input

第一行一个整数N,表示单词个数。 下面有N行,每行一个单词。


Output

共N行,每行一个单词,是对应上面的N个单词化简后的单词。


Sample Input

3 abc efg ijh


Sample Output

a e I


Hint

数据范围 单词数N,1≤N≤50;每个单词的长度不超过50;并且单词都有小写字母构成。 保证所给单词没有一个单词是另一个单词的前缀。

#include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<string> #include<cstdio> using namespace std; int n; string s[55]; int num=0; struct pointt { int tr[26],cd; pointt() {cd=0;} }a[2505]; void ins(string s) { int len=s.size(),p=0; for(int i=0;i<len;i++) { int ch=int(s[i]-'a'); if(a[p].tr[ch]==0) a[p].tr[ch]=++num; p=a[p].tr[ch]; a[p].cd++; } } void matchh(string s) { int len=s.size(),p=0; for(int i=0;i<len;i++) { int ch=int(s[i]-'a'); printf("%c",s[i]); p=a[p].tr[ch]; if(a[p].cd==1) { cout<<endl; break; } } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>s[i]; ins(s[i]); } for(int i=1;i<=n;i++) matchh(s[i]); return 0; }

 

转载请注明原文地址: https://www.6miu.com/read-5038306.html

最新回复(0)