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!]

 

 

 

 

 

 

 

 

 

 

 

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