Skip to content

Commit 2280169

Browse files
Merge pull request #202 from Liam0205/18_hashtable
[cpp][18_hashtable] impl in C++
2 parents 8eb0fed + 479c64c commit 2280169

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

c-cpp/18_hashtable/.gitkeep

Whitespace-only changes.

c-cpp/18_hashtable/hash_map.cc

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/**
2+
* Created by Liam Huang (Liam0205) on 2018/08/14.
3+
* This is an old test file for hash_map, created by Liam.
4+
* Just for showing the inner logic for hash_map class template.
5+
* Original posted on:
6+
* https://github.com/Liam0205/leetcode/tree/master/met/hash_map.cc
7+
*/
8+
9+
#include <iostream>
10+
#include <utility>
11+
#include <vector>
12+
#include <functional>
13+
#include <memory>
14+
15+
template <typename Key, typename T, typename Hash = std::hash<Key>>
16+
class hash_map {
17+
public:
18+
using key_type = Key;
19+
using mapped_type = T;
20+
using value_type = std::pair<const key_type, mapped_type>;
21+
using size_type = size_t;
22+
using hasher = std::hash<Key>;
23+
24+
private: // helper
25+
using wrapper = std::shared_ptr<value_type>;
26+
27+
public: // constructor
28+
hash_map() {
29+
container_.resize(primes_[size_level_]);
30+
}
31+
32+
public: // capacity
33+
bool empty() const { return empty_; }
34+
size_type size() const { return size_; }
35+
size_type max_size() const { return primes_[size_level_]; }
36+
37+
public: // find and modify
38+
mapped_type& operator[](const key_type& key) {
39+
auto hashed = find_hash(key);
40+
if (not(container_[hashed]) and construct_new_on_position(hashed, key) and
41+
load_factor() > max_load_factor()) {
42+
expand();
43+
}
44+
return container_[hashed]->second;
45+
}
46+
47+
public: // hash policy
48+
double load_factor() const { return static_cast<double>(size()) / max_size(); }
49+
double max_load_factor() const { return max_load_factor_; }
50+
void expand() const {
51+
++size_level_;
52+
std::vector<wrapper> temp;
53+
temp.resize(primes_[size_level_]);
54+
for (auto w : container_) {
55+
if (nullptr != w) {
56+
auto hashed = find_hash(w->first);
57+
temp[hashed] = w;
58+
}
59+
}
60+
container_ = std::move(temp);
61+
}
62+
63+
private: // helper functions
64+
size_type find_hash(const key_type& key) const {
65+
const size_t csz = container_.size();
66+
size_t count = 0;
67+
size_t hashed = hasher_(key) % csz;
68+
while (nullptr != container_[hashed] and container_[hashed]->first != key) {
69+
hashed = (hashed + ++count) % csz;
70+
}
71+
return hashed;
72+
}
73+
bool construct_new_on_position(const size_type pos, const key_type& key) {
74+
empty_ = false;
75+
++size_;
76+
container_[pos] = std::make_shared<value_type>(std::make_pair(key, mapped_type()));
77+
return true;
78+
}
79+
80+
private:
81+
const hasher hasher_ = hasher();
82+
mutable size_t size_level_ = 0;
83+
mutable std::vector<wrapper> container_;
84+
static const size_t primes_[];
85+
bool empty_ = true;
86+
size_type size_ = 0;
87+
double max_load_factor_ = 0.75;
88+
};
89+
template <typename Key, typename T, typename Hash>
90+
const size_t hash_map<Key, T, Hash>::primes_[] = {7, 17, 29, 53, 101, 211, 401, 809, 1601, 3203}; // ...
91+
92+
int main() {
93+
hash_map<int, int> test;
94+
test[1];
95+
test[2] = 2;
96+
std::cout << test[1] << ' ' << test[2] << std::endl;
97+
return 0;
98+
}

0 commit comments

Comments
 (0)