POJ 2408:Anagram Groups

这题用了两个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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值