1

题目大意:

给定N个数字插入到用户指定长度为MSize的hash表中,如果X无法插入就输出X cannot be inserted.紧接着给出M个查询的数字,计算平均M个数字的查找时间。

算法思路:

首先对于输入的hash表长度MSize得判断是否为素数,如果不是,需要将其增加为最小素数table_size,其次对于插入过程,如果当前数字num的插入位置没有冲突就直接插入其中,否则就进行正向平方探针法查找插入位置,如果查找了table_size步还没有查找到插入位置,说明无法插入。对于查找过程:如果查找的位置上的数字等于当前数字说明查找成功,否则进行正向平方探针进行查询,直到查找成功,或者遇到0(没有数字),每一次进行hash运算,都得算作一次查找操作,一个数字最多查找table_size+1次。

注意点:

  • 1、对于查询失败的情形为2种,第一种是找到数字为0的位置,代表根本没有数字插入到该位置,第二种是该查询数字没有插入到hash表中,该情形需要查询table_size+1次后回到初始位置才知道查询失败。

提交结果:

image.png

AC代码:

#include<cstdio>
#include<cmath>

using namespace std;

int hash_table[10006];

bool isPrime(int n){
    if(n<=1) return false;
    int sqrtn = (int)sqrt(n*1.0);
    for(int i=2;i<=sqrtn;++i){
        if(n%i==0) return false;
    }
    return true;
} 

int getPrimeTableSize(int n){
    while(!isPrime(n)){
        ++n;
    }
    return n;
}

int main(){
    int MSize,N,M;
    scanf("%d %d %d",&MSize,&N,&M);
    int table_size = getPrimeTableSize(MSize);
    for(int i=0;i<N;++i){
        // 插入N个数字
        int num;
        scanf("%d",&num);
        int pos = -1;// 插入位置 
        for(int step=0;step<table_size;++step){
            // 最多table_size步,查找不到插入位置就说明无法插入
            int p = (num+step*step)%table_size;
            if(hash_table[p]==0){
                pos = p;
                break;
            }
        }
        if(pos==-1){
            printf("%d cannot be inserted.\n",num);
            continue;
        }
        // 查找到插入位置
        hash_table[pos] = num;
    }
    // 查找M个数字
    int cnt = 0;// 查找总次数 
    for(int i=0;i<M;++i){
        int num;
        scanf("%d",&num);
        for(int step=0;step<=table_size;++step){
            // 最多table_size+1步,查找不到就说明没有 
            int p = (num+step*step)%table_size;
            ++cnt;
            if(hash_table[p]==num||hash_table[p]==0){
                break;
            }
        }
    }
    printf("%.1lf",cnt*1.0/M);
    return 0;
} 

乔梓鑫
569 声望17 粉丝

主要分享个人学习经验和心得