题目:分组统计
问题描述
先输入一组数,然后输入其分组,按照分组统计出现次数并输出,参见样例。
输入格式
输入第一行表示样例数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;
}
这个题我没有太好的方法,以上方法没有很好的利用到哈希表的特性,代码还是相对冗长,没有“空间换时间”,但是个人认为这种方法比较好想。