题目大意:
给定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次后回到初始位置才知道查询失败。
提交结果:
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;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。