xdoj 分组统计

题目:分组统计

问题描述

先输入一组数,然后输入其分组,按照分组统计出现次数并输出,参见样例。

输入格式

输入第一行表示样例数m,对于每个样例,第一行为数的个数n,接下来两行分别有n个数,第一行有n个数,第二行的n个数分别对应上一行每个数的分组,n不超过100。数和分组号的值都不超过10000。

输出格式

按顺序输出各个样例的结果。输出格式参见样例,按组号从小到大输出,组内数字也按编号从小到大输出。

样例输入

1

7

3 2 3 8 8 2 3

1 2 3 2 1 3 1

样例输出

1={2=0,3=2,8=1}

2={2=1,3=0,8=1}

3={2=1,3=1,8=0}

样例说明

第一组中2出现0次,3出现2次,8出现一次

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
typedef struct Hash//用此结构体数组作为哈希表,下标作为组数
{
	int flag;//表明存在一组
	int value[10000];//哈希表,这一组中的元素作为下标,这个数组中的值存储出现次数
}Hash;
Hash hash[10000];//全局变量,在堆申请空间,否则在主函数里申请会StackOverflow
int main()
{
	int m;
	int i, j, k, l;
	scanf("%d", &m);
	for (l = 0; l < m; l++)
	{
		int n;
		scanf("%d", &n);
		int value[100], group[100];//输入组号和对应元素
		for (i = 0; i < n; i++)
			scanf("%d", &value[i]);
		for (i = 0; i < n; i++)
			scanf("%d", &group[i]);
		for (i = 0; i < 10000; i++)//初始化哈希表
		{
			for (j = 0; j < 10000; j++)
			{
				hash[i].value[j] = -1;//因为要输出所有输入的元素的出现次数,有些元素有可能出现次数为零
			}
			hash[i].flag = 0;
			for (j = 0; j < n; j++)//遍历一遍输入的元素,初始化为0,方便后续自加 和 输出时的判断
			{
				hash[i].value[value[j]] = 0;
			}
		}
		for (i = 0; i < n; i++)//利用组号和元素作为下标构造哈希表
		{
			hash[group[i]].flag = 1;
			hash[group[i]].value[value[i]]++;
		}
		for (i = 0; i < 10000; i++)//遍历整个哈希表,因为是按下标存储,输出的顺序就是升序
		{
			if (hash[i].flag == 1)
			{
				printf("%d={", i);
				for (j = 0; j < 10000; j++)//先打印一组,后面的多加个逗号再打印
				{
					if (hash[i].value[j] != -1)
					{
						printf("%d=%d", j, hash[i].value[j]);
						j++;
						break;
					}
				}
				for (; j < 10000; j++)
				{
					if (hash[i].value[j] != -1)
					{
						printf(",%d=%d", j, hash[i].value[j]);
					}
				}
				printf("}\n");
			}
		}
	}
	return 0;
}

这个题我没有太好的方法,以上方法没有很好的利用到哈希表的特性,代码还是相对冗长,没有“空间换时间”,但是个人认为这种方法比较好想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值