这题用了两个sort,大sort是把每个等价类先排到相邻的位置上去,第二个sort在等价类内部排序,第三个 sort 将 等价类排序。
//这题要考虑的太多,主要的一点是重复单词只输出一次但是计算Group size的时候要重复计算
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct word0 {
char conten[500];
int size;
short nun[26];
}word[30005];
struct wordset
{
int head;
int tail;
int size;
}wset[30005];
int Strcmp(const void *a, const void *b)
{
return strcmp((char*)a, (char*)b);
}
int judge(short *a, short *b)//等价类判断
{
for (int i = 0; i < 26; i++)
if (a[i] != b[i])
return a[i] - b[i];
return 0;
}
int comp(const void *a, const void *b)
{
if (((word0 *)a)->size != ((word0 *)b)->size)
return ((word0 *)a)->size - ((word0 *)b)->size;
else
return judge(((word0 *)a)->nun, ((word0 *)b)->nun);
}
int comp2(const void*a, const void*b)
{
if (((wordset*)a)->size != ((wordset*)b)->size)
return ((wordset*)b)->size - ((wordset*)a)->size;
else
return strcmp(word[((wordset*)a)->head].conten, word[((wordset*)b)->head].conten);
}
int main()
{
int counter = 0, i;
while (scanf("%s", word[counter].conten) != EOF)
{
i = 0;
while (word[counter].conten[i] != '\0')
{
word[counter].nun[word[counter].conten[i] - 'a']++;
++i;
}
word[counter].size = i;
++counter;
}
qsort(word, counter, sizeof(word0), comp);
int head = 0, tail = 0, setnum = 0;
wset[0].head = 0;
for (tail = 0; tail < counter; ++tail)
if (comp(word + head, word + tail) != 0)
{
wset[setnum].tail = tail - 1;
wset[setnum].size = tail - head;
setnum++;
wset[setnum].head = head = tail;
}
if (wset[setnum].head != counter)
{
wset[setnum].tail = counter - 1;
wset[setnum].size = wset[setnum].tail - wset[setnum].head + 1;
}
else
setnum--;
setnum++;
int kind = setnum;
if (kind > 5)
kind = 5;
int j, pianyi;
for (int i = 0; i< setnum; ++i)
{
pianyi = 0;
qsort(word + wset[i].head, wset[i].size, sizeof(word0), Strcmp);
for ( j = wset[i].head; j <= wset[i].tail&& j+pianyi +1<= wset[i].tail;)
{
if (strcmp(word[j].conten, word[j+pianyi+1].conten) == 0)
{
pianyi++;
}
else
{
j++;
strcpy(word[j].conten, word[pianyi + j].conten);
}
}
wset[i].tail = j;
}
qsort(wset, setnum, sizeof(wordset), comp2);
for (int i = 0; i < kind; ++i)
{
printf("Group of size %d:", wset[i].size);
for (int j = wset[i].head; j <= wset[i].tail; j++)
{
printf(" %s", word[j].conten);
}
printf(" .\n");
}
return 0;
}