-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHashMap.cpp
More file actions
214 lines (161 loc) · 5.01 KB
/
HashMap.cpp
File metadata and controls
214 lines (161 loc) · 5.01 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#include <iostream>
#define THRESHOLD (0.70)
using namespace std;
template<typename K, typename V>
class node {
public:
K key;
V value;
node<K, V> *next;
node(K key, V value) {
this->key = key;
this->value = value;
}
~node() {
// first delete the pointed node // leads to a chain to delete the entire ll
delete next;
}
};
template<typename K, typename V>
class HashMap {
private:
int n; // Number of elements currently stored
int m; // Number of buckets
node<K, V> **buckets;
int hashcode(int key) {
return key % m;
}
int hashcode(string key) {
const int PRIME = 43;
int res = 0;
int pow = 1;
// hash calculation formula:-
// eg str = Apple
// hash = A*PRIME^0 + p* PRIME^1 + p*PRIME^2 +...e*PRIME^4
for (char ch : key) {
res += ch * pow;
pow = pow * PRIME;
pow %= m; // prevent integer overflow
res %= m; // prevent integer overflow
}
return res;
}
void resize() {
node<K, V> **oldbuckets = buckets;
int num_old_buckets = m;
// TODO: set m to next closest prime
m = (m << 1) | 1; // make almost twice as large; odd number is more likely to be a prime
n = 0;
buckets = new node<K, V> *[m];
for (int i = 0; i < m; i++)
buckets[i] = nullptr;
// Insert old data into new table
for (int i = 0; i < num_old_buckets; i++) {
auto temp = oldbuckets[i];
if (temp != nullptr) {
// ll exists in current bucket
while (temp != nullptr) {
insert(temp->key, temp->value);
temp = temp->next;
}
delete oldbuckets[i]; // calls the destructor of node
}
}
delete[] oldbuckets; // delete the old buckets array
}
public:
HashMap(int bucket_count = 11) {
this->n = 0;
this->m = bucket_count;
this->buckets = new node<K, V> *[this->m];
for (int i = 0; i < m; i++)
this->buckets[i] = nullptr; // cleanup and garbage references
}
void insert(K key, V value) {
int i = hashcode(key);
auto *temp = new node<K, V>(key, value);
temp->next = this->buckets[i]; // set to the head of ll that the bucket points to.
this->buckets[i] = temp; // temp is now the new head of ll
this->n += 1; // increase the number of elements in our hashmap
float load_factor = (float) this->n / this->m;
// check to see if we need rehashing
if (load_factor > THRESHOLD) {
resize();
}
}
// TODO: remove this function before submission
// Print it
void print() {
///Iterate over buckets array
for (int i = 0; i < m; i++) {
///Print the LL for each buckets
node<K, V> *temp = buckets[i];
cout << "Bucket " << i << "->";
while (temp != nullptr) {
cout << temp->key << ",";
temp = temp->next;
}
cout << endl;
}
}
V *find(K key) {
int idx = hashcode(key); // idx = index of bucket possibly containing the key
node<K, V> *ptr = buckets[idx];
while (ptr != nullptr) {
if (ptr->key == key)
return &(ptr->value);
ptr = ptr->next;
}
return nullptr;
}
bool erase(K key) {
int idx = hashcode(key);
node<K, V> *prev = nullptr;
node<K, V> *ptr = buckets[idx];
while (ptr != nullptr) {
if (ptr->key == key)
break;
prev = ptr;
ptr = ptr->next;
}
if (ptr == nullptr) {
// key not found
return false;
}
// else found the key to be deleted
if (prev == nullptr) {
// node to be deleted is at the head of the ll of the bucket
buckets[idx] = ptr->next;
} else {
prev->next = ptr->next;
}
// can't use delete here
// bcoz it will call the destructor which will delete entire ll starting from ptr
free(ptr);
n -= 1;
return true;
}
};
int main() {
HashMap<string, string> strStrMap;
strStrMap.insert("IIIT-H", "CSE");
strStrMap.insert("IIIT-B", "CSE");
strStrMap.insert("IIT-B", "CSE");
strStrMap.insert("IIT-M", "MS-CSE");
strStrMap.insert("BITS", "SS");
strStrMap.insert("ISI", "CS");
strStrMap.print();
strStrMap.erase("IIIT-B");
strStrMap.print();
HashMap<int, int> int_int_map;
int_int_map.insert(11, 100);
int_int_map.insert(22, 527);
int_int_map.insert(33, 127);
int_int_map.insert(44, 99);
int_int_map.insert(55, 4);
int_int_map.insert(66, 44);
int_int_map.print();
auto it = int_int_map.find(22);
if (it != nullptr)
cout << *it << endl;
}