-
Notifications
You must be signed in to change notification settings - Fork 0
/
MidSquareMethodHashTable.java
137 lines (120 loc) · 3.49 KB
/
MidSquareMethodHashTable.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import java.util.ArrayList;
import java.util.List;
import static java.lang.Math.abs;
/**
* Square the value of the key k i.e. k^2
* Extract the middle r digits as the hash value.
*/
public class MidSquareMethodHashTable {
private static int M = 400;
private List<DLinkedList<Customer>> data = new ArrayList<>(M);
MidSquareMethodHashTable() {
for (int i = 0; i < M; ++i) {
data.add(new DLinkedList<>());
}
}
/**
* Add {@param customer} into hash table.
*
* @param customer The entry to be added
* @return true when add successfully (no same content entry in this hash table yet)
*/
public boolean put(Customer customer) {
int bucket = hashCustomer(customer);
DLinkedList list = data.get(bucket);
if (list == null) {
list = new DLinkedList<Customer>();
list.Append(customer);
data.set(bucket, list);
} else {
if (list.Search(customer) != null) {
return false;
}
list.Append(customer);
}
return true;
}
/**
* Whether the hash table contains the entry.
*
* @param customer The entry we want to check the existence
* @return true if contains, false otherwise
*/
public boolean contains(Customer customer) {
int bucket = hashCustomer(customer);
DLinkedList list = data.get(bucket);
return list != null && list.Search(customer) != null;
}
/**
* Remove the entry from the hash table.
*
* @param customer The entry we want to remove
* @return true if remove successfully, false otherwise
*/
public boolean remove(Customer customer) {
int bucket = hashCustomer(customer);
DLinkedList list = data.get(bucket);
if (list == null) {
return false;
}
DLinkedList.Node node = list.Search(customer);
if (node == null) {
return false;
}
list.Delete(customer);
return true;
}
/**
* Get the number of collisions in this hash table.
*
* @return
*/
public int getNumberOfCollision() {
int ret = 0;
for (int i = 0; i < data.size(); ++i) {
int bucketItemCount = data.get(i).Count();
if (bucketItemCount > 1) {
ret += data.get(i).Count() - 1;
}
}
return ret;
}
public void printEachBucketDetails() {
for (int i = 0; i < data.size(); ++i) {
System.out.print(data.get(i).Count() + " ");
}
System.out.println();
}
private int hashCustomer(Customer customer) {
int square = customer.hashCode() * customer.hashCode();
int digitsCount = digitCount(square);
// We will get mid 3 digits
int divider = 1;
for (int i = 0; i < (digitsCount - 3)/2; ++i) {
divider *= 10;
}
square /= divider;
square %= 1000;
return abs(square) % M;
}
/**
* Return the number of digits in {@param a}.
*
* Say when {@param a} is 12, return 2; when {@param a} is 0, return 1, when {@param a} is 12356, return 5;
* when {@param a} is 7463460, return 7 etc
*
* @param a
* @return
*/
private static int digitCount(int a) {
if (a == 0) {
return 1;
}
int count = 0;
while (a != 0) {
++count;
a /= 10;
}
return count;
}
}