世界著名的A.N.Agram教授目前的研究涉及大型变位词组。他刚刚发现了一个新的应用,为他的理论在英语文本中的字符分布。给定这样的文本,您将找到最大的变位词组。
文本是一系列单词。一个单词w是一个单词v的变位词,如果且仅当字符位置的某些排列p带w到v时。那么,w和v在同一个变位词组中。变位词组的大小是该组中的单词数。找到5个最大的变位词组。
输入
输入包含由小写字母字符组成的单词,用空格(或新行)分隔。它由EOF终止。你可以假设不会超过30000个单词。
输出
输出5个最大的变位词组。如果少于5组,则全部输出。按减小的大小对组进行排序。用词典编纂的最小元素在词典编纂上打破联系。对于每个组输出,打印其大小和成员字。按字典顺序对成员词排序,并只打印一次相同的词。
Sample Input
undisplayed
trace
tea
singleton
eta
eat
displayed
crate
cater
carte
caret
beta
beat
bate
ate
abet
Sample Output
Group of size 5: caret carte cater crate trace .
Group of size 4: abet bate beat beta .
Group of size 4: ate eat eta tea .
Group of size 1: displayed .
Group of size 1: singleton .
题意就是这样,从一堆字符串中找到 字符串可以交换位置就一样的同样的字符串,并将相同形式的字符串都放在一起(按原来字典序排序),一开始就直接 set数组,map 之间查找,直接超时。还是写字典树吧。
将每个单词最后的一个节点进行查询,如果没有被标记,就是一个新的单词,就将它放到一个新的结构体中的set 中,如果已经被标记就在原来的结构体中插入就可以了 ,字典树在某些方面还是很好用的,在字典树中就可以简单找到该单词的最终节点,再来一个计数器,将这个单词插入到制定下表的结构体中。
最后在遍历输出5个set集合,就可以了。
#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
#include<set>
#include<string>
#include<string.h>
using namespace std;
#include<sstream>
const int maxn=1e6+5;
int tree[maxn][30];
int tot;
int anstot;
int vis[maxn];
int num[30];
char s[maxn];
struct point
{
int num;
set<string>mp;
}zifu[maxn];
bool cmp(const point &a ,const point &b )
{
if(a.num==b.num)
{
return *(a.mp.begin()) < *(b.mp.begin());
}
return a.num>b.num;
}
void insert(char *s)
{
int root=0;
int len=strlen(s);
string t=s; //字典序的字符串
/*for(int i=0;i<len;i++)
num[s[i]-'a']++;
for(int i=0;i<26;i++)
{
while(num[i]!=0)
{
t+=(i+'a');
num[i]--;
}
}*/
sort(t.begin(),t.end());
for(int i=0;i<len;i++)
{
int x=t[i]-'a';
if(!tree[root][x])
tree[root][x]=++tot;
root=tree[root][x];
}
if(!vis[root])
vis[root]=++anstot;
zifu[vis[root]].num++;
string tmp=s;
zifu[vis[root]].mp.insert(tmp);
return ;
}
int main()
{
while(scanf("%s",s)!=EOF)
{
insert(s);
}
sort(zifu+1,zifu+1+anstot,cmp);
for(int i=1;i<=5;i++)
{
printf("Group of size %d: ",zifu[i].num);
set<string>::iterator it;
for(it=zifu[i].mp.begin();it!=zifu[i].mp.end();++it)
printf("%s ",(*it).c_str());
printf(".\n");
}
return 0;
}
在每个单词在判断是否可以(进行排序可以成为一类单词),我们就直接用sort 库函数,直接将插入的串排序,然后再套字典树模板将最后节点标记了(并用计数器来计数)。如果单词已经存在,那么最后的 root 就会出现过,就直接插入到已存在的结构体中。
get it;