AlgoPlus v0.1.0
Loading...
Searching...
No Matches
hash_table.h
1#ifndef HASH_TABLE_H
2#define HASH_TABLE_H
3
4#ifdef __cplusplus
5#include <cstdint>
6#include <functional>
7#include <iostream>
8#include <list>
9#include <optional>
10#include <string>
11#include <unordered_map>
12#include <vector>
13#endif
14
32template <typename KeyType, typename ValueType> class hash_table {
33 public:
34 using BucketType = std::unordered_map<size_t, std::list<std::pair<KeyType, ValueType>>>;
35
41 inline explicit hash_table(std::vector<std::pair<KeyType, ValueType>> v = {}) {
42 if (!v.empty()) {
43 for (auto& x : v) {
44 this->insert(x.first, x.second);
45 }
46 }
47 }
48
54 inline hash_table(const hash_table& h) : bucketList(h.bucketList), hash(h.hash) {}
55
61 inline hash_table& operator=(const hash_table& h) {
62 if (&this == h) {
63 return *this;
64 }
65 bucketList = h.bucketList;
66 hash = h.hash;
67 return *this;
68 }
69
73 inline ~hash_table() { bucketList.clear(); }
74
83 inline void insert(const KeyType& key, const ValueType& value) {
84 auto& list = bucketList[hash(key)];
85 for (auto& pair : list) {
86 if (pair.first == key) {
87 pair.second = value;
88 return;
89 }
90 }
91 list.emplace_back(key, value);
92 }
93
100 inline std::optional<ValueType> retrieve(const KeyType& key) {
101 auto& list = bucketList[hash(key)];
102 for (auto& pair : list) {
103 if (pair.first == key) {
104 return pair.second;
105 }
106 }
107 return std::nullopt;
108 }
109
118 inline void remove(const KeyType& key) {
119 auto& list = bucketList[hash(key)];
120 list.remove_if([key](const auto& pair) { return pair.first == key; });
121 }
122
123 class Iterator;
124
125 inline Iterator begin() {
126 auto startIterator = bucketList.begin();
127 while (startIterator != bucketList.end() && startIterator->second.empty()) {
128 startIterator++;
129 }
130 return Iterator(startIterator, bucketList.end());
131 }
132
133 inline Iterator end() { return Iterator(bucketList.end(), bucketList.end()); }
134
139 inline friend std::ostream& operator<<(std::ostream& out, hash_table<KeyType, ValueType>& h) {
140 out << '[';
141 for (auto& [key, list] : h.bucketList) {
142 for (auto& pair : h.bucketList[key]) {
143 out << "{" << pair.first << ", " << pair.second << "} ";
144 }
145 out << '\n';
146 }
147 out << ']';
148 return out;
149 }
150
151 private:
152 std::hash<KeyType> hash;
153 BucketType bucketList;
154};
155
159template <typename KeyType, typename ValueType> class hash_table<KeyType, ValueType>::Iterator {
160 private:
161 using BucketIterator = typename BucketType::iterator;
162 using ListIterator = typename std::list<std::pair<KeyType, ValueType>>::iterator;
163 BucketIterator bucketIter, bucketEnd;
164 ListIterator listIter;
165
166 std::unordered_map<size_t, std::list<std::pair<KeyType, ValueType>>> bucketList;
167 std::vector<size_t> key_values;
168 int64_t index{};
169
170 public:
176 explicit Iterator(BucketIterator start, BucketIterator end)
177 : bucketIter(start), bucketEnd(end) {
178 if (bucketIter != bucketEnd) {
179 listIter = bucketIter->second.begin();
180 }
181 }
182
189 Iterator&
190 operator=(const std::unordered_map<size_t, std::list<std::pair<KeyType, ValueType>>>& bucket) {
191 this->bucketList = bucket;
192 return *(this);
193 }
194
201 if (++listIter == bucketIter->second.end()) {
202 while (++bucketIter != bucketEnd && bucketIter->second.empty())
203 ;
204 if (bucketIter != bucketEnd) {
205 listIter = bucketIter->second.begin();
206 }
207 }
208 return *this;
209 }
210
217 Iterator it = *this;
218 ++*(this);
219 return it;
220 }
221
228 if (this->index > 0) {
229 this->index--;
230 }
231 return *(this);
232 }
233
240 Iterator it = *this;
241 --*(this);
242 return it;
243 }
244
253 bool operator!=(const Iterator& it) const {
254 return this->bucketIter != it.bucketIter ||
255 (bucketIter != bucketEnd && this->listIter != it.listIter);
256 }
257
264 std::pair<KeyType, ValueType>& operator*() { return *listIter; }
265};
266
267#endif // HASH_TABLE_H
Iterator class.
Definition hash_table.h:159
std::pair< KeyType, ValueType > & operator*()
operator * for Type Iterator
Definition hash_table.h:264
Iterator & operator--()
operator – for type Iterator
Definition hash_table.h:227
Iterator & operator=(const std::unordered_map< size_t, std::list< std::pair< KeyType, ValueType > > > &bucket)
operator = for hash table iterator class
Definition hash_table.h:190
Iterator operator--(int)
operator – for type Iterator
Definition hash_table.h:239
bool operator!=(const Iterator &it) const
operator != for Type Iterator
Definition hash_table.h:253
Iterator(BucketIterator start, BucketIterator end)
Construct a new Iterator object.
Definition hash_table.h:176
Iterator & operator++()
operator ++ for type Iterator
Definition hash_table.h:200
Iterator operator++(int)
operator ++ for type Iterator
Definition hash_table.h:216
hash_table & operator=(const hash_table &h)
operator = for the hash_table class
Definition hash_table.h:61
void insert(const KeyType &key, const ValueType &value)
Inserts a key-value pair into the hash table.
Definition hash_table.h:83
std::optional< ValueType > retrieve(const KeyType &key)
Retrieves the value associated with the given key.
Definition hash_table.h:100
hash_table(const hash_table &h)
Copy constructor of the hash_table.
Definition hash_table.h:54
friend std::ostream & operator<<(std::ostream &out, hash_table< KeyType, ValueType > &h)
<< operator for hash_table class
Definition hash_table.h:139
void remove(const KeyType &key)
Removes the key-value pair associated with the given key from the hash table.
Definition hash_table.h:118
hash_table(std::vector< std::pair< KeyType, ValueType > > v={})
Construct a new hash table object.
Definition hash_table.h:41
~hash_table()
Destroy the hash table object.
Definition hash_table.h:73