9. 同构词分组

我们现在做一个单词游戏,游戏规则为将给定的一系列单词按照同构词(由相同字母组成,但可能顺序不同的单词)规则进行分组。例如:

eat tea tan ate nat bat

上述为5个单词,按照同构词的规则,我们可以将其分为三组

ate eat tea
bat
nat tan

现在请你编程实现同构词的分组。

输入

输入包含两行,第一行输入整数 n(1 ≤ n ≤ 50)表示单词的个数,第二行输入 n 个单词,单词间用空格分隔,每个单词由26个小写字母(a~z)组成,且每个单词的长度不超过10个字符。

输出

输出为分组后的单词,每组一行,组内及组间的单词顺序按字典序排列,如上述示例。


测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助
测试用例 1以文本方式显示
  1. 6↵
  2. eat tea tan ate nat bat↵
以文本方式显示
  1. ate eat tea↵
  2. bat↵
  3. nat tan↵
1秒1024KB0



#include<cstdio>//AC
#include<cstring>
#include<cstdlib>

int n, last = 0;
char str[65][25] = { '\0' }, str2[65][25] = { '\0' };
int num[65] = { -1 }, strnum[65][65] = { 0 };
int numm[65] = { 0 };
int cmp1(const void *a, const void *b)
{
	return *(char *)a - *(char *)b;
}
void cmp2(void)
{
	for (int i = 0; i < last; i++)
	{
		for (int j = 0; j < last - 1; j++)
		{
			int cm = strcmp(str[strnum[numm[j]][1]], str[strnum[numm[j+1]][1]]);
			if (cm > 0)
			{
				int jh = numm[j];
				numm[j] = numm[j + 1];
				numm[j + 1] = jh;
			}
		}
	}
}
void ZuSort(int last)
{
	for (int i = 1; i <= strnum[last][0]; i++)
	{
		for (int j = 1; j < strnum[last][0]; j++)
		{
			int mm = strcmp(str[strnum[last][j]], str[strnum[last][j + 1]]);
			if (mm > 0)
			{
				int xx = strnum[last][j];
				strnum[last][j] = strnum[last][j + 1];
				strnum[last][j + 1] = xx;
			}
		}
	}
}

int main()
{
	memset(num, -1, sizeof(num));
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%s", str[i]);
		strcpy(str2[i], str[i]);
	}
	for (int i = 0; i < n; i++)
	{
		int len = strlen(str2[i]);
		qsort(str2[i], len, sizeof(str2[i][0]), cmp1);
	}
	for (int i = 0; i < n; i++)//分组
	{
		if (num[i] < 0)
		{
			num[i] = 1;
			int nn = 1;
			strnum[last][nn] = i;
			strnum[last][0] = 1;
			for (int j = i + 1; j < n; j++)
			{
				if (num[j]<0)
				{
					int ans = strcmp(str2[i], str2[j]);
					if (ans == 0)
					{
						nn++;
						num[j] = 1;
						strnum[last][nn] = j;
						strnum[last][0]++;
					}
				}
			}
			last++;
		}
	}
	for (int i = 0; i < last; i++)//组内排序
	{
		ZuSort(i);
	}
	for (int i = 0; i < last; i++)
		numm[i] = i;//strnum[i] 'i'-->numm[i]
	cmp2(); //组间排序

	//输出顺序排序
	for (int i = 0; i < last; i++)
	{
		for (int j = 1; j <= strnum[numm[i]][0]; j++)
		{
			if (j <= strnum[numm[i]][0] - 1)
				printf("%s ", str[strnum[numm[i]][j]]);
			else
				printf("%s\n", str[strnum[numm[i]][j]]);
		}
	}

	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值