分组统计【知识点:set,散列—二维数组实现链地址法(数组尾部作为Link)】


http://codeup.cn/problem.php?cid=100000582&pid=1

题目

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

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

输出
输出m行,格式参见样例,按从小到大排。

样例输入
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}

分析

1.变量

全局变量
【题目条件n<100那么n<maxn,若设数组则有0—101,用101做Link】

const int maxn=102;
int n,m;

对于每一组样例
未处理的数Num,去重排序过后的数NumUi
tmp暂存的分组号,去重排序过后的分组号Class
按照分组号在分组号的一位数组中插入数(未累积重复出现的次数)table[分组号][Link]
Link的解释:其中table[tmp][maxn - 1]++使得队尾元素【101】(n不超过100必不会达到101)在不断变大,作为下一个要插入的数组的下标以及当前数组中的数的个数

int Num[maxn]={},tmp,table[maxn][maxn]={};
set<int>NumUi;
set<int>Class;

2.输入

for(int i=0;i<n;i++){
            //写入未处理的Num数,以便对应table;
            //写入STL容器NumUI即为去重排序过后的数,表示{?=%d}
                scanf("%d",&Num[i]);
                NumUi.insert(Num[i]);
            }
            for(int i=0;i<n;i++){
            //tmp为暂存的分组号
            //写入STL容器Class即为去重排序过后的分组号
            //按照分组号在分组号的一位数组中插入数(未累积重复出现的次数)
            //table[tmp][maxn - 1]++使得队尾元素【101】(n不超过100必不会达到101)在不断变大,作为下一个要插入的数组的下标以及当前数组中的数的个数
                scanf("%d",&tmp);
                Class.insert(tmp);
                table[tmp][table[tmp][maxn-1]++]=Num[i];
            }

3.输出

3.0累积重复出现的次数

//tmp为暂存的数在该分组中的数量
tmp=0;
for(int i=0;i<100;i++){//注意上限不是maxn是100(n不超过100)
	if(table[*cls][i]==*num)
		tmp++;
	}
printf("%d",tmp);

3.1

因为不知道如何找倒数第二个元素;
所以只能这么写,判定是否为第一个来写,
每一个的最后再}\n

or(set<int>::iterator cls=Class.begin();cls!=Class.end();cls++){
                printf("%d={",*cls);
                for(set<int>::iterator num=NumUi.begin();num!=NumUi.end();num++){
                    printf("%s%d=",num==NumUi.begin()?"":",",*num);
                    //tmp为暂存的数在该分组中的数量
                    tmp=0;
                    for(int i=0;i<100;i++){//注意上限不是maxn是100(n不超过100)
                        if(table[*cls][i]==*num)
                            tmp++;
                    }
                    printf("%d",tmp);
                }
                printf("}\n");
            }

AC代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=102;
int n,m;

int main()
{
    while(scanf("%d",&m)!=EOF)
    {
        while(m--)
        {
            scanf("%d",&n);
            int Num[maxn]={},tmp,table[maxn][maxn]={};
            set<int>NumUi;
            set<int>Class;
            for(int i=0;i<n;i++){
            //写入未处理的Num数,以便对应table;
            //写入STL容器NumUI即为去重排序过后的数,表示{?=%d}
                scanf("%d",&Num[i]);
                NumUi.insert(Num[i]);
            }
            for(int i=0;i<n;i++){
            //tmp为暂存的分组号
            //写入STL容器Class即为去重排序过后的分组号
            //按照分组号在分组号的一位数组中插入数(未累积重复出现的次数)
            //table[tmp][maxn - 1]++使得队尾元素【101】(n不超过100必不会达到101)在不断变大,作为下一个要插入的数组的下标以及当前数组中的数的个数
                scanf("%d",&tmp);
                Class.insert(tmp);
                table[tmp][table[tmp][maxn-1]++]=Num[i];
            }
            for(set<int>::iterator cls=Class.begin();cls!=Class.end();cls++){
                printf("%d={",*cls);
                for(set<int>::iterator num=NumUi.begin();num!=NumUi.end();num++){
                    printf("%s%d=",num==NumUi.begin()?"":",",*num);
                    //tmp为暂存的数在该分组中的数量
                    tmp=0;
                    for(int i=0;i<100;i++){//注意上限不是maxn是100(n不超过100)
                        if(table[*cls][i]==*num)
                            tmp++;
                    }
                    printf("%d",tmp);
                }
                printf("}\n");
            }
        }
    }
    return 0;
}

写题过程中的错误

错误代码

以id[1000100]作为hash表;1000100为表长;H(key)=组号*100+数
数的大小没说在100以内,100010仍有可能会有数组越界或者重复

#include<bits/stdc++.h>
using namespace std;
int n,m,id[1000100]= {};
void hash(int x,int y,int num[])//组号*100+数
{
    num[x*100+y]++;
    return;
}
int main()
{
    while(scanf("%d",&m)!=EOF)
    {
        while(m--)
        {
            scanf("%d",&n);
            int x,y[n];
            memset(id,0,sizeof(id));
            set<int>fz;
            set<int>zno;
            for(int i=0; i<n; i++)
            {
                scanf("%d",&y[i]);
                fz.insert(y[i]);
            }
            for(int i=0; i<n; i++)
            {
                scanf("%d",&x);
                zno.insert(x);
                hash(x,y[i],id);
            }
            for(set<int>::iterator it=zno.begin(); it!=zno.end(); it++)
            {
                printf("%d={",*it);
                for(set<int>::iterator its=fz.begin(); its!=fz.end(); its++)
                    printf("%s%d=%d",its==fz.begin()?"":",",*its,id[*it*100+*its]);
                printf("}\n");
            }
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章