PAT_甲级_1145 Hashing - Average Search Time (25point(s)) (C++)【哈希表/平方正向探测法】

目录

1,题目描述

题目描述

2,思路

算法

3,AC代码

4,解题过程

第一搏

第二搏


1,题目描述

Sample Input:

4 5 4
10 6 4 15 11
11 4 15 2

 

Sample Output:

15 cannot be inserted.
2.8

题目描述

先在哈希表中插入一些数据,然后给出一系列数据进行查找(找到/不存在),并求出平均查找次数;

 

2,思路

算法

  1. 确定MSize,就是寻找比初始MSize大的最小质数:
  2. 向哈希表中插入数据:            
  3. 计算每次查找的次数:                                           

 

3,AC代码

#include<bits/stdc++.h>
using namespace std;
int MSize, N, M, table[20005], num; // !!!10005不够
bool isPrime(int x){
    if(x <= 1) return false;
    for(int i = 2; i <= sqrt(x); i++)
        if(x % i == 0)
            return false;
    return true;
}
void insert(const int x){
    int i, pos;
    for(i = 0; i < MSize; i++){
        pos = (x + i * i) % MSize;
        if(table[pos] == 0){
            table[pos] = x;
            break;
        }
    }
    if(table[pos] != x){
        printf("%d cannot be inserted.\n", x);
    }
}
int find(const int x){
    int i, pos;
    for(i = 0; i < MSize; i++){
        pos = (x + i * i) % MSize;
        if(table[pos] == x || table[pos] == 0){// !!!注意条件
            break;
        }
    }
    return i + 1;
}
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
    scanf("%d%d%d", &MSize, &N, &M);
    while(!isPrime(MSize)) MSize++;
    for(int i = 0; i < N; i++){
        scanf("%d", &num);
        insert(num);
    }
    double sum = 0;
    for(int i = 0; i < M; i++){
        scanf("%d", &num);
        sum += find(num);
    }
    printf("%.1f", sum * 1.0 / M);
    return 0;
}

4,解题过程

第一搏

@&再见萤火虫& 【PAT_甲级_1078 Hashing (25point(s)) (C++)【哈希表/平方探测法】】这题很像,于是不假思索: 

#include<bits/stdc++.h>
using namespace std;
int MSize, N, M, table[10005], num;
bool isPrime(int x){
    if(x <= 1) return false;
    for(int i = 2; i <= sqrt(x); i++)
        if(x % i == 0)
            return false;
    return true;
}
void insert(int num){
    int i;
    for(i = 0; i < MSize; i++){
        int pos = (num + i * i) % MSize;
        if(table[pos] == 0){
            table[pos] = num;
            break;
        }
    }
    if(i == MSize){
        printf("%d cannot be inserted.\n", num);
    }
}
int find(int num){
    int i;
    for(i = 0; i < MSize; i++){
        int pos = (num + i * i) % MSize;
        if(table[pos] == num || table[pos] == 0){// !!!注意条件
            return i + 1;
        }
    }
    return i + 1;
}
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE

    scanf("%d%d%d", &MSize, &N, &M);
    while(!isPrime(MSize)) MSize++;
    for(int i = 0; i < N; i++){
        scanf("%d", &num);
        insert(num);
    }
    double sum = 0;
    for(int i = 0; i < M; i++){
        scanf("%d", &num);
        //cout<<num <<' '<<find(num)<<endl;
        sum += find(num);
    }
    printf("%.1f", sum / M);
    return 0;
}

第二搏

这类题目的细节需要特别的注意!

查阅了其他大佬的做法之后,注意到两点:

1,在插入/查找的时候是否需要到达MSize?

经过测试,发现不到MSize也是可以通过的。

2,table初始大小的设计:

为了简化main函数的内容,使代码结构更清晰,我采用了设计函数的方法,插入数据为insert,查找数据为find;

为了减少函数的参数,将table数组放在了全局变量,因而必须提前定下大小(不能等MSize最终值计算出来之后再设置大小);

一开始规模为10000,所以我就设置大小为10005,如第一次测试,于是我干脆把规模改为20005,终于通过了(o゜▽゜)o☆[BINGO!]

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章