经典入门_Hash的应用

Hash:将存储位置与数据本身对应掐来的存储手段就是Hash

例2.5 统计通成绩学生人数(1018)

题目描述:读入n(n<=1000)名学生的成绩(0~100,整型)(当读到n时结束),将获得某一给定分数的学生人数输出。

样例输入:
3
80 60 90
60 
2
85 66
0
5
60 75 90 55 75
75
0
样例输出:
1
0
2
#include<stdio.h>

int main(){
    int n,tmp,num;
    int buf[101];
    while(scanf("%d",&n)!=EOF&&n!=0){
        for(int i=0;i<=100;i++)//也可直接定义为int Hash[101]={0}; 
            buf[i]=0;
        for(int i=0;i<n;i++){
            scanf("%d",&tmp);
            buf[tmp]++;
        }
        scanf("%d",&num);
        printf("%d\n",buf[num]);
    }
    return 0;
}

 

例2.6 Sort (1431)

题目描述:给你n个整数,请按从大到小的顺序输出前m大的数。第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且处于区间[-500000,500000]的整数。

样例输入:
5 3
3 -35 92 213 -644
样例输出:
213 92 3

由于代排序数字的数量十分庞大(1000000),即使使用快排也仍有可能超时。而哈希只需要从尾到头遍历数组,其时间复杂度仍在百万数量级,解法符合要求。

由于输入数据中出现了负数,于是我们不能直接把输入数据当做数组下标来访问数组元素,而是将每一个输入的数据都加上一个固定偏移值,使数据区间映射到数组下标区间。

本题还要注意在最后一个数字之后不存在空格。

#include<stdio.h>
int Hash[1000001];//在函数内部的静态数组是在栈上分配空间所以不能开得太大,而全局的数组是在数据段分配空间所以可以弄大些。如果在函数内部开大数组可能产生栈溢出。

int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=0;i<=1000000;i++)
            Hash[i]=0;
        for(int i=1;i<=n;i++){
            int tmp;
            scanf("%d",&tmp);
            Hash[tmp+500000]++;
        }
        for(int i=1000000;i>=0;i--){
            if(Hash[i]!=0){
                printf("%d",i-500000);
                m--;
                if(m!=0) printf(" ");
                else{
                    printf("\n");
                    break;
                }
            }    
        }
    }
    return 0;
} 

 

posted @ 2018-02-04 00:28  Johnny、  阅读(151)  评论(0编辑  收藏  举报