PAT 1078. Hashing
还是考书本上的概念,就是如何应对hash时的碰撞情况,有open adressing和chaining,目前接触到的都是chaining。开放地址法在当初学的时候对几种形式也没去太关注,即
1. 线性探测(hash(key) + 0, 1, 2, 3...m-1)
2. 二次探测(hash(key) + 0, 1, 4, 9...(m-1)^2)
3. 双重散列(hash(key) +0, 1*hash2(key), 2 * hash2(key)...(m-1)*hash2(key))
m为当前散列表的大小,即探测至多m次(包含了第一次hash(key)+0),原来学数据结构的时候就有疑问(特别是用二次探测做题目),尼玛这一直探测下去没完没了了啊,其实不是这样。
那么这题就简单了
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 5 using namespace std; 6 7 bool is_prime(unsigned int n) { 8 if (n <= 1) return false; 9 if (n == 2) return true; 10 for (int i=2; i * i <= n; i++) { 11 if (n % i == 0) { 12 return false; 13 } 14 } 15 return true; 16 } 17 18 void print(int M, int i, int num) { 19 if (i != 0) { 20 printf(" "); 21 } 22 if (num < 0) { 23 printf("-"); 24 } else { 25 printf("%d", num); 26 } 27 28 if (i == M - 1) { 29 printf("\n"); 30 } 31 } 32 33 int main() { 34 35 unsigned int M, N; 36 cin>>M>>N; 37 38 if (!is_prime(M)) { 39 while (!is_prime(++M)); 40 } 41 42 bool* hashtable = new bool[M]; 43 for (int i=0; i<M; i++) { 44 hashtable[0] = false; 45 } 46 47 for (int i=0; i<N; i++) { 48 int num; 49 cin>>num; 50 int addr = num % M; 51 unsigned int taddr; 52 bool found = false; 53 for (unsigned int j = 0; j<M; j++) { 54 taddr = (addr + j * j) % M; 55 if (!hashtable[taddr]) { 56 hashtable[taddr] = true; 57 found = true; 58 break; 59 } 60 } 61 if (found) { 62 print(M, i, taddr); 63 } else { 64 print(M, i, -1); 65 } 66 } 67 68 system("pause"); 69 return 0; 70 }