-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhashmap.cpp
More file actions
81 lines (81 loc) · 2.29 KB
/
hashmap.cpp
File metadata and controls
81 lines (81 loc) · 2.29 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
using std::size_t;
enum class node_state {FREE,IN_USE,ERASED};
template<typename _Key, typename _Value>
struct node {
_Key key;
_Value value;
node_state state = node_state::FREE;
};
template<typename _Key, typename _Value, typename _Hash = std::hash<_Key>>class hash_map {
public:
hash_map(size_t capacity): capacity(capacity), size(0) {
nodes = new node<_Key,_Value>[capacity];
for (size_t i = 0; i < capacity; i++)
nodes[i] = node<_Key,_Value>();
}
hash_map(): hash_map(3) {}
size_t count(const _Key& key) const {
size_t index = get_index(key, capacity);
for (size_t d = 0; d < capacity; d++) {
if (nodes[index].state == node_state::FREE)
return false;
if (nodes[index].state == node_state::IN_USE
&& nodes[index].key == key)
return true;
index++;
if (index == capacity)
index = 0;
}
return false;
}
_Value& operator[](const _Key& key) {
if ((size << 1) > capacity)
rehash();
size_t index;
bool result = put(key, index, nodes, capacity);
if (result)
size++;
return nodes[index].value;
}
~hash_map() {delete[] nodes;}
private:
size_t get_index(const _Key& key, size_t size) const {
return (h(key) * 22543) % size;
}
void rehash() {
size_t n_capacity = (capacity << 1);
node<_Key, _Value>* n_nodes = new node<_Key, _Value>[n_capacity];
for (size_t i = 0; i < n_capacity; i++)
n_nodes[i] = node<_Key,_Value>();
for (size_t i = 0; i < capacity; i++)
if (nodes[i].state == node_state::IN_USE) {
size_t index;
put(nodes[i].key, index, n_nodes, n_capacity);
n_nodes[index].value = nodes[i].value;
}
delete[] nodes;
nodes = n_nodes;
capacity = n_capacity;
}
bool put(const _Key& key, size_t& index, node<_Key,_Value>* nodes, size_t nodes_length) {
index = get_index(key, nodes_length);
for (size_t i = 0; i < nodes_length; i++) {
if (nodes[index].state == node_state::FREE
|| nodes[index].state == node_state::ERASED) {
nodes[index].key = key;
nodes[index].state = node_state::IN_USE;
return true;
}
if (nodes[index].key == key)
return false;
index++;
if (index == nodes_length)
index = 0;
}
throw std::logic_error("Unexpected case.");
}
size_t capacity;
size_t size;
node<_Key, _Value>* nodes;
_Hash h;
};