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 }

 

posted @ 2015-03-04 16:36  卖程序的小歪  阅读(218)  评论(0编辑  收藏  举报