【POJ 2408 Anagram Groups】 字典树(Trie树)

匿名 (未验证) 提交于 2019-12-03 00:26:01

POJ2408
本题题意是,把可以通过重新排列变成相同单词的单词放入一个集合,最后按找集合元素由多到少输出前五个集合,如果几何元素相同,按照字典序由小到大输出
我们考虑,如果两个单词可以通过重新排列组合变成相同单词,那么他们的字典序最小的排列方式一定是相同的,所以我们可以利用每个元素的最小排列方式判定是否在同一个集合,字典树在这里用于判定某个字符串时候出现过。最后用set来保存以便维持字典序
POJ2408代码

#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<set> #include<vector> using namespace std; const int maxn = 1e6+5; int tree[maxn][30]; char ss[maxn]; int tot,anstot; int num[30]; int vis[maxn]; struct data {     int num;     set<string> s; }cnt[maxn]; bool cmp(const data &a,const data &b) {     if(a.num==b.num)     {         return *(a.s.begin())<*(b.s.begin());     }     return a.num>b.num; } void insert_(char *str) {     int root=0;     int len= strlen(str);     string str2="";     for(int i=0;i<len;i++)     {         num[str[i]-'a']++;     }     for(int i=0;i<26;i++)//在此转换为字典序最小的字符串     {         while(num[i]!=0)         {             str2+=(i+'a');             num[i]--;         }     }     for(int i=0;i<len;i++)     {         int id=str2[i]-'a';         if(!tree[root][id]) tree[root][id]=++tot;         root=tree[root][id];     }     if(!vis[root])  vis[root]=++anstot;//若未出现过,赋予编号     cnt[vis[root]].num++;//将此字符串所在的结构体num变量+1     string tmp=str;     cnt[vis[root]].s.insert(tmp);     return ; } int main() {     while(scanf("%s",ss)!=EOF)     {         insert_(ss);     }     sort(cnt+1,cnt+1+anstot,cmp);     for(int i=1;i<=5;i++)     {         printf("Group of size %d: ",cnt[i].num);         set<string>::iterator it;         for(it=cnt[i].s.begin();it!=cnt[i].s.end();++it)         {             printf("%s ",(*it).c_str());         }         printf(".\n");     }     return 0; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!