9.同构词分组

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

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

ate eat tea
bat
nat tan
现在请你编程实现同构词的分组。

输入

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

输出

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

测试用例
in:
6
eat tea tan ate nat bat
out:
ate eat tea↵
bat↵
nat tan↵

当前有n个词要分组,当前已有m个组。当前处理ni词,对应查找mj组。对于ni内每个字母nik,查找是否出现在mj词中,如果都出现找到了,记录mj分组增加ni。否则查找下一个组,直到都没有找到,则创建新分组。创建分组过程是每增加一个字母都要查找是否已经存在这个字母如果存在则不重复放入。简化可以先把每个词排序并去重。然后分组只是比较字符串是否相同,相同则归入一组,不同则增加一个新组。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int n, team=0;
char str[65][25],str2[65][25];
int flag[65] = { 0 },strnum[65][65] = { 0 },num[65] = { 0 };
int cmp(const void *a, const void *b)
{
	return strcmp((char *)a,(char *)b);
}
void teamsort(int team)
{
	for (int i = 1; i <= strnum[team][0]; i++)
	{
		for (int j = 1; j < strnum[team][0]; j++)
		{
			if (strcmp(str[strnum[team][j]], str[strnum[team][j + 1]]) > 0)
			{
				int t1 = strnum[team][j];
				strnum[team][j] = strnum[team][j + 1];
				strnum[team][j + 1] = t1;
			}
		}
	}
}
int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%s", str[i]);
	for (int i = 0; i < n; i++)
		strcpy(str2[i], str[i]);
	for (int i = 0; i < n; i++)
		qsort(str2[i], strlen(str2[i]), sizeof(str2[i][0]), cmp);
	memset(flag, 0, sizeof(flag));
	for (int i = 0; i < n; i++)
	{
		if (flag[i] == 0)
		{
			flag[i] = 1;
			int t = 1;
			strnum[team][t] = i;
			strnum[team][0] = 1;
			for (int j = i + 1; j < n; j++)
			{
				if (flag[j]==0&&strcmp(str2[i], str2[j]) == 0)
				{
					t++;
					flag[j] = 1;
					strnum[team][t] = j;
					strnum[team][0]++;
				}
			}
			team++;
		}
	}
	for (int i = 0; i < team; i++)
		teamsort(i);
	for (int i = 0; i < team; i++)
		num[i] = i;
	for (int i = 0; i < team; i++)
	{
		for (int j = 0; j < team - 1; j++)
		{
			if (strcmp(str[strnum[num[j]][1]], str[strnum[num[j+1]][1]]) > 0)
			{
				int t2 = num[j];
				num[j] = num[j + 1];
				num[j + 1] = t2;
			}
		}
	}
	for (int i = 0; i < team; i++)
	{
		for (int j = 1; j <= strnum[num[i]][0]; j++)
		{
			if (j <= strnum[num[i]][0] - 1)
				printf("%s ", str[strnum[num[i]][j]]);
			else
				printf("%s\n", str[strnum[num[i]][j]]);
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ArgentumHook/article/details/83050955