题目大意
输入多个单词,相同字母异序词归为一组,按照每组单词数量从大到小输出前5组(不够全输出),两组数量相同则按照字典序输出,并按照字典序输出每组的单词。
思路
先将每个单词s1的每个字母按照字典序排序(目的是使单词同源)得到s2,并把排序前后的两个字符串打包到一个结构体中。然后按照优先s2,其次s1的规则sort排序,得到有序(字典序)的一组结构体数组。for循环遍历找出有几组相同字母异序词,并按照优先数量其次字典序的规则排序,输出前五组即可。
AC代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <math.h>
using namespace std;
struct node//存放每个单词
{
char s1[40];
char s2[40];
} str[30005];
struct xu //存放每组相同字母异序词的信息
{
int start;//在str数组中开始的位置
int con;//数量
char s[40];//组中字典序最小的单词
} Node[30005];
bool cmpw(node a,node b)
{
if(strcmp(a.s2,b.s2)==0)
return strcmp(a.s1,b.s1)<0;
else
return strcmp(a.s2,b.s2)<0;
}
bool cmp(xu a,xu b)
{
if(a.con==b.con)
return strcmp(a.s,b.s)<0;
else
return a.con>b.con;
}
int main()
{
int n=0;
while(~scanf("%s",str[n].s1))
{
int len=strlen(str[n].s1);
strcpy(str[n].s2,str[n].s1);
sort(str[n].s2,str[n].s2+len);//这里可以直接用sort非常方便!看了别人的代码是用桶排的
n++;//统计单词个数
}
sort(str,str+n,cmpw);//按照字典序排序
int m=1;//统计组数
Node[0].start=0;
Node[0].con=1;
strcpy(Node[0].s,str[0].s1);//注意是将s1赋过去,因为前面已经按照字典序最小排序了,所以易知此为组中最小单词
for(int i=1; i<n; i++)//遍历全部单词,统计共有多少不同的组
{
if(strcmp(str[i].s2,str[i-1].s2)==0)
Node[m-1].con++;
else
{
strcpy(Node[m].s,str[i].s1);
Node[m].start=i;
Node[m].con=1;
m++;
}
}
sort(Node,Node+m,cmp);//按照数量和字典序排序
for(int i=0; i<5; i++)//输出前5组
{
int t=Node[i].start;
if(i>=m)//不足5组全部输出后break;
{
printf("\n");
break;
}
printf("Group of size %d:",Node[i].con);
printf(" %s",str[t].s1);
for(int j=1;j<Node[i].con;j++)
{
if(strcmp(str[t+j].s1,str[t+j-1].s1)==0)
continue;
printf(" %s",str[t+j].s1);
}
printf(" .\n");
}
return 0;
}