字符串关键字的散列映射 (25 分)【详细解析】
立志用最少的代碼做最高效的表達
給定一系列由大寫英文字母組成的字符串關(guān)鍵字和素數(shù)P,用移位法定義的散列函數(shù)H(Key)將關(guān)鍵字Key中的最后3個字符映射為整數(shù),每個字符占5位;再用除留余數(shù)法將整數(shù)映射到長度為P的散列表中。例如將字符串AZDEG插入長度為1009的散列表中,我們首先將26個大寫英文字母順序映射到整數(shù)0~25;再通過移位將其映射為3×32^2+4×32+6=3206;然后根據(jù)表長得到3206 % 1009 = 179,即是該字符串的散列映射位置。
發(fā)生沖突時請用平方探測法解決。
輸入格式:
輸入第一行首先給出兩個正整數(shù)N(≤500)和P(≥2N的最小素數(shù)),分別為待插入的關(guān)鍵字總數(shù)、以及散列表的長度。第二行給出N個字符串關(guān)鍵字,每個長度不超過8位,其間以空格分隔。
輸出格式:
在一行內(nèi)輸出每個字符串關(guān)鍵字在散列表中的位置。數(shù)字間以空格分隔,但行末尾不得有多余空格。
輸入樣例1:
4 11
HELLO ANNK ZOE LOLI
輸出樣例1:
3 10 4 0
輸入樣例2:
6 11
LLO ANNA NNK ZOJ INNK AAA
輸出樣例2:
3 0 10 9 6 1
題意:先將字符串的最后三個字符序列化(如:BCD=1?322+2?321+3?320BCD=1*32^2+2*32^1+3*32^0BCD=1?322+2?321+3?320),然后將該數(shù)對p取余,用平方探測法插入到合適的位置。
注意:
1、Hash數(shù)組的初始值最好設(shè)為-1,因為諸如A、AA、AAA等的編碼值都為0,他們會彼此沖突。
2、在向左探索,也就是相減時,要加+p后再取余,避免出現(xiàn)<0的情況。
3、使用unordered_map來進行判重。
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<unordered_map> using namespace std;int strHash(string s) { //返回每一個hash序列的值 reverse(s.begin(), s.end());int sum = 0, num = 0;for(auto i : s) {sum += (i-'A')*pow(32, num);num++;if(num == 3) break; //最大為2 }return sum; }int main() {int n, p; cin >> n >> p;unordered_map<string, int>um;int Hash[p] = {0};fill(Hash, Hash+p, -1); //賦為-1 for(int i = 0; i < n; i++) {if(i != 0) cout << ' ';string s; cin >> s;if(um.count(s)) { cout << um[s]; continue; }int num = strHash(s);int y = num%p;int tmp_y = y;int n1 = 1, n2 = 1;//選擇位置 while(Hash[tmp_y] != -1) {tmp_y = y; //做臨時變量 //若為奇數(shù),則+,若為偶數(shù),則-//注意:在減的時候,為防止出現(xiàn)<0的情況,要+p if(n2 % 2 != 0) {tmp_y = (tmp_y+n1*n1)%p;n2++;}else {tmp_y = (tmp_y-n1*n1+p)%p;n2++; n1++;}}Hash[tmp_y] = num; um[s] = tmp_y;cout << tmp_y; }return 0; }
耗時
弱小和無知不是生存的障礙,傲慢才是。???????——《三體》
總結(jié)
以上是生活随笔為你收集整理的字符串关键字的散列映射 (25 分)【详细解析】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 社交网络图中结点的“重要性”计算 (30
- 下一篇: 整型关键字的平方探测法散列 (25 分)