PAT A1145 Hashing - Average Search Time
Sample Input:
4 5 4
10 6 4 15 11
11 4 15 2
Sample Output:
15 cannot be inserted.
2.8
word | meaning |
---|---|
Quadratic probing (with positive increments only) | 平方探测法(只考虑正向) |
-
分析:
这句话的意思是,第三行的M个数,是待查询元素 -
思路 1: 同A 1078Hashing
- 首先按照平方探测的规则填数,没法插入的输出;
- 累加总查找次数,对每个待查找元素,进行平方探测,step从0取到t_size
2-1 当满足hash表对应位置为空,或命中时跳出查找:成功时的查找次数为step
2-2 当查找到step == t_size时,查找失败,step+1为失败时的查找次数
- code 1:
#include <iostream>
using namespace std;
const int maxn = 100010;
int has[maxn], search_times[maxn];
bool isPrime(int x){
if(x == 1) return false;
for(int i = 2; i*i <= x; ++i)
if(x % i == 0) return false;
return true;
}
int getPrime(int x){
while(!isPrime(x)) x++;
return x;
}
int main(){
int m_size, n, m, tmp;
scanf("%d %d %d", &m_size, &n, &m);
int t_size = getPrime(m_size);
for(int i = 0; i < n; ++i){
scanf("%d", &tmp);
int key = tmp % t_size;
int step = 0;
while(step < t_size){
int next = (key + step * step) % t_size;
step++;
if(has[next] == 0){
has[next] = tmp;
break;
}
}
if(step == t_size) printf("%d cannot be inserted.\n", tmp);
}
int q, sumTimes = 0;
for(int i = 0; i < m; ++i){
scanf("%d", &q);
int key = q % t_size;
int step = 0, next;
while(step <= t_size){ //!!!Wrong 1:见下:查找要多查找一次,即进入查找失败节点
next = (key + step * step) % t_size;
step++;
if(has[next] == 0 || has[next] == q){
break;
}
}
//!!!:Wrong 1:查找时当step == t_size时还有可能查找成功:只有查找失败step才多+1
// if(step == t_size) step++;
sumTimes += step;
}
printf("%.1f", 1.0 * sumTimes / m);
return 0;
}
-
Wrong 1:
查找比插入要多探测一次,即进入查找失败节点
因为:当step == t_size时还有可能查找成功(成功直接返回step):只有查找失败step才多+1 -
T2 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int has[maxn], times[maxn];
bool p[maxn];
void GetPrime(){
p[1] = true; //Wrong 1: 样例1,记得把1也删掉 = true;
for(int i = 2; i < maxn; ++i){
if(p[i] == false){ //Wrong 1:记得先判断i是不是素数 再筛
for(int j = i + i; j < maxn; j += i){
p[j] = true;
}
}
}
}
//bool isPrime(int x){
// if(x < 2) return false;
// int sqr = sqrt(1.0 * x);
// for(int i = 2; i <= sqr; ++i){ //Wrong 1:!!!别忘了 =号
// if(x % i == 0) return false;
// }
// return true;
//}
int main(){
GetPrime();
int m_size, n, m;
scanf("%d %d %d", &m_size, &n, &m);
for(int i = m_size; i < maxn; ++i){
// if(isPrime(i)){
if(p[i] == false){
m_size = i;
break;
}
}
int tmp;
for(int i = 0; i < n; ++i){
scanf("%d", &tmp);
int step = 0, ori = tmp % m_size;
while(step < m_size){
int pos = (ori + step * step) % m_size;
step++;
if(has[pos] == 0){
has[pos] = tmp;
break;
}
}
if(step == m_size){
step++;
printf("%d cannot be inserted.\n", tmp);
}
times[tmp] = step;
}
double avg = 0.0;
for(int i = 0; i < m; ++i){
scanf("%d", &tmp);
if(times[tmp] > 0){
avg += times[tmp];
}else{
int step = 0, ori = tmp % m_size;
while(step <= m_size){
int pos = (ori + step * step) % m_size;
step++;
if(has[pos] == 0){
break;
}
}
avg += step;
}
}
printf("%.1f", avg / m);
return 0;
}
- T3 code:
#include <bits/stdc++.h>
using namespace std;
bool isPrime(int x)
{
if(x < 2) return false;
int sqr = sqrt(1.0 * x);
for(int i = 2; i <= sqr; ++i)
{
if(x % i == 0) return false;
}
return true;
}
int GetTsize(int x)
{
while(!isPrime(x)) x++;
return x;
}
vector<int> table;
bool Insert(int x, int Tsize)
{
int step = 1, key = x % Tsize;
int nex = key;
while(table[nex] != 0 && step < Tsize)
{
nex = (key + step * step) % Tsize;
step++;
}
if(table[nex] != 0) return false;
table[nex] = x;
return true;
}
int Find(int x, int Tsize)
{
int step = 1, key = x % Tsize;
int nex = key;
while(step <= Tsize)
{
if(table[nex] == 0 || table[nex] == x) break; //WRONG!!!
nex = (key + step * step) % Tsize;
step++;
}
return step;
}
int main()
{
int msize, n, m;
scanf("%d %d %d", &msize, &n, &m);
msize = GetTsize(msize);
table.resize(msize+1);
for(int i = 0; i < n; ++i)
{
int tmp;
scanf("%d", &tmp);
if(Insert(tmp, msize) == false) printf("%d cannot be inserted.\n", tmp);
}
int sum = 0;
for(int i = 0; i < m; ++i)
{
int tmp;
scanf("%d", &tmp);
sum += Find(tmp, msize);
}
printf("%.1f", 1.0 * sum / m);
return 0;
}
- T4 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10100;
int table[maxn];
bool isPrime(int x)
{
if(x < 2) return false;
for(int i = 2; i * i <= x; ++i)
{
if(x % i == 0) return false;
}
return true;
}
int GetTSize(int x)
{
while(!isPrime(x)) x++;
return x;
}
unordered_map<int, int> SearchTime;
void InsertTable(int x, int TSize)
{
int pos = x % TSize;
for(int i = 0; i < TSize; ++i)
{
int nex = (pos + i * i) % TSize;
if(table[nex] == 0)
{
table[nex] = x;
SearchTime[x] = i + 1;
return;
}
}
printf("%d cannot be inserted.\n", x);
SearchTime[x] = TSize + 1;
}
int Search(int x, int TSize)
{
int pos = x % TSize;
for(int i = 0; i < TSize; ++i)
{
int nex = (pos + i * i) % TSize;
if(table[nex] == x || table[nex] == 0) //找到了 || 没找到
{
return i + 1;
}
}
return TSize + 1;
}
int main()
{
int MSize, n, m;
scanf("%d %d %d", &MSize, &n, &m);
MSize = GetTSize(MSize);
for(int i = 0; i < n; ++i)
{
int tmp;
scanf("%d", &tmp);
InsertTable(tmp, MSize);
}
int SumSearchTime = 0;
for(int i = 0; i < m; ++i)
{
int tmp;
scanf("%d", &tmp);
if(SearchTime[tmp] != 0)
{
SumSearchTime += SearchTime[tmp];
}else
{
SumSearchTime += Search(tmp, MSize);
}
}
printf("%.1f", 1.0 * SumSearchTime / m);
return 0;
}