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 }

 

你可能感兴趣的:(hash)