这一题是求哈希表的平均搜索时间。哈希函数:
H
(
k
e
y
)
=
k
e
y
%
T
S
i
z
e
H(key)=key\%TSize
H(key)=key%TSize,解决冲突使用平方探测(只取正数部分,范围:
1
−
T
S
i
z
e
1-TSize
1−TSize)。
T
S
i
z
e
TSize
TSize要取比原来的
T
S
i
z
e
TSize
TSize大素数中的最小的一个。
一开始插入时,分开两个部分,先使用哈希函数,有冲突再使用平方探测,后来发现这两个可以合在一起。后面提交,发现第一和第三测试点一直通不过,比较了一下别人的源码,也没看出差在哪里。后来我发现是X cannot be inserted.,我最后没加那一点。
做这一题时,才知道练习的重要性。像平方探测方法,平时有学习过的,但一直没使用过,使用起来发现自己平时理解有点问题。
#include <bits/stdc++.h>
using namespace std;
int getSmallPrime(int mSize)
{
int sqrtSize = sqrt(mSize);
bool prime = true;
for(int i=2; i<=sqrtSize; i++) {
if(mSize%i==0) {
prime = false;
break;
}
}
if(prime) {
return mSize;
}
for(int i=mSize+1;; i++) {
sqrtSize = sqrt(i);
prime = true;
for(int j=2; j<=sqrtSize; j++) {
if(i%j==0) {
prime = false;
break;
}
}
if(prime) {
mSize = i;
break;
}
}
return mSize;
}
int main()
{
int mSize,n,m;
scanf("%d%d%d",&mSize,&n,&m);
vector<int> inputNum;
vector<int> queryNum;
int x;
for(int i=0; i<n; i++) {
scanf("%d",&x);
inputNum.push_back(x);
}
for(int i=0; i<m; i++) {
scanf("%d",&x);
queryNum.push_back(x);
}
mSize = getSmallPrime(mSize);
int hashTable[mSize]= {0};
int index = 0;
for(int i=0; i<n; i++) {
bool insertNum = false;
for(int j=0; j<=mSize; j++) {
index=(inputNum[i] + j*j)%mSize;
if(hashTable[index]==0) {
hashTable[index] = inputNum[i];
insertNum = true;
break;
}
}
if(!insertNum) {
printf("%d cannot be inserted.\n",inputNum[i]);
}
}
int sumTime = 0;
int oneTime = 0;
for(int i=0; i<m; i++) {
oneTime = 0;
for(int j=0; j<=mSize; j++) {
index=(queryNum[i] + j*j)%mSize;
oneTime++;
if(hashTable[index]==queryNum[i] || hashTable[index]==0) {
break;
}
}
sumTime += oneTime;
}
printf("%.1lf\n",1.0*sumTime/m);
return 0;
}