namespace my_stl {
template<class K> struct HashFunc {
size_t operator()(const K& key) { return (size_t)key; }
};
template<> struct HashFunc<string> {
size_t operator()(const string& key) {
size_t hash = 0;
for (auto e : key) {
hash *= 131;
hash += e;
}
return hash;
}
};
namespace hash_bucket {
template<class T> struct HashNode {
T _data;
HashNode<T>* _next;
HashNode(const T& data) :_data(data), _next(nullptr) {}
};
template<class K, class T, class KeyOfT, class Hash>
class HashTable;
template<class K, class T, class Ptr, class Ref, class KeyOfT, class Hash>
struct HTIterator {
typedef HashNode<T> Node;
typedef HTIterator Self;
Node* _node;
const HashTable<K, T, KeyOfT, Hash>* _pht;
HTIterator(Node* node, const HashTable<K, T, KeyOfT, Hash>* pht)
:_node(node), _pht(pht) {}
Ref operator*() { return _node->_data; }
Ptr operator->() { return &_node->_data; }
bool operator!=(const Self& s) { return _node != s._node; }
Self& operator++() {
if (_node->_next) {
_node = _node->_next;
} else {
KeyOfT kot;
Hash hs;
size_t hashi = hs(kot(_node->_data)) % _pht->_tables.size();
++hashi;
while (hashi < _pht->_tables.size()) {
if (_pht->_tables[hashi]) break;
++hashi;
}
if (hashi == _pht->_tables.size()) {
_node = nullptr;
} else {
_node = _pht->_tables[hashi];
}
}
return *this;
}
};
template<class K, class T, class KeyOfT, class Hash>
class HashTable {
friend struct HTIterator<K, T, T*, T&, KeyOfT, Hash>;
friend struct HTIterator<K, T, const T*, const T&, KeyOfT, Hash>;
typedef HashNode<T> Node;
public:
typedef HTIterator<K, T, T*, T&, KeyOfT, Hash> Iterator;
typedef HTIterator<K, T, const T*, const T&, KeyOfT, Hash> ConstIterator;
Iterator Begin() {
if (_n == 0) return End();
for (size_t i = 0; i < _tables.size(); i++) {
if (_tables[i]) return Iterator(_tables[i], this);
}
return End();
}
Iterator End() { return Iterator(nullptr, this); }
ConstIterator Begin() const {
if (_n == 0) return End();
for (size_t i = 0; i < _tables.size(); i++) {
if (_tables[i]) return ConstIterator(_tables[i], this);
}
return End();
}
ConstIterator End() const { return ConstIterator(nullptr, this); }
inline unsigned long __stl_next_prime(unsigned long n) {
static const unsigned long primes[] = {
53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
49157, 98317, 196613, 393241, 786433, 1572869, 3145739,
6291469, 12582917, 25165843, 50331653, 100663319, 201326611,
402653189, 805306457, 1610612741, 3221225473, 4294967291
};
const unsigned long* first = primes;
const unsigned long* last = primes + sizeof(primes)/sizeof(primes[0]);
const unsigned long* pos = lower_bound(first, last, n);
return pos == last ? *(last - 1) : *pos;
}
HashTable() { _tables.resize(__stl_next_prime(_tables.size()), nullptr); }
~HashTable() {
for (size_t i = 0; i < _tables.size(); i++) {
Node* cur = _tables[i];
while (cur) { Node* next = cur->_next; delete cur; cur = next; }
_tables[i] = nullptr;
}
}
pair<Iterator, bool> Insert(const T& data) {
KeyOfT kot;
Iterator it = Find(kot(data));
if (it != End()) return make_pair(it, false);
Hash hs;
size_t hashi = hs(kot(data)) % _tables.size();
if (_n == _tables.size()) {
vector<Node*> newtables(__stl_next_prime(_tables.size() + 1), nullptr);
for (size_t i = 0; i < _tables.size(); i++) {
Node* cur = _tables[i];
while (cur) {
Node* next = cur->_next;
size_t new_hashi = hs(kot(cur->_data)) % newtables.size();
cur->_next = newtables[new_hashi];
newtables[new_hashi] = cur;
cur = next;
}
_tables[i] = nullptr;
}
_tables.swap(newtables);
hashi = hs(kot(data)) % _tables.size();
}
Node* newnode = new Node(data);
newnode->_next = _tables[hashi];
_tables[hashi] = newnode;
++_n;
return make_pair(Iterator(newnode, this), true);
}
Iterator Find(const K& key) {
KeyOfT kot;
Hash hs;
size_t hashi = hs(key) % _tables.size();
Node* cur = _tables[hashi];
while (cur) {
if (kot(cur->_data) == key) return Iterator(cur, this);
cur = cur->_next;
}
return End();
}
bool Erase(const K& key) {
KeyOfT kot;
Hash hs;
size_t hashi = hs(key) % _tables.size();
Node* prev = nullptr;
Node* cur = _tables[hashi];
while (cur) {
if (kot(cur->_data) == key) {
if (!prev) _tables[hashi] = cur->_next;
else prev->_next = cur->_next;
delete cur;
--_n;
return true;
}
prev = cur;
cur = cur->_next;
}
return false;
}
private:
vector<Node*> _tables;
size_t _n = 0;
};
}
}
namespace my_stl {
template<class K, class Hash = HashFunc<K>>
class unordered_set {
struct SetKeyOfT {
const K& operator()(const K& key) { return key; }
};
public:
typedef typename hash_bucket::HashTable<K, const K, SetKeyOfT, Hash>::Iterator iterator;
typedef typename hash_bucket::HashTable<K, const K, SetKeyOfT, Hash>::ConstIterator const_iterator;
iterator begin() { return _ht.Begin(); }
iterator end() { return _ht.End(); }
const_iterator begin() const { return _ht.Begin(); }
const_iterator end() const { return _ht.End(); }
pair<iterator, bool> insert(const K& key) { return _ht.Insert(key); }
iterator Find(const K& key) { return _ht.Find(key); }
bool Erase(const K& key) { return _ht.Erase(key); }
private:
hash_bucket::HashTable<K, const K, SetKeyOfT, Hash> _ht;
};
}
namespace my_stl {
template<class K, class V, class Hash = HashFunc<K>>
class unordered_map {
struct MapKeyOfT {
const K& operator()(const pair<K, V>& kv) { return kv.first; }
};
public:
typedef typename hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT, Hash>::Iterator iterator;
typedef typename hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT, Hash>::ConstIterator const_iterator;
iterator begin() { return _ht.Begin(); }
iterator end() { return _ht.End(); }
const_iterator begin() const { return _ht.Begin(); }
const_iterator end() const { return _ht.End(); }
pair<iterator, bool> insert(const pair<K, V>& kv) { return _ht.Insert(kv); }
V& operator[](const K& key) {
pair<iterator, bool> ret = _ht.Insert(make_pair(key, V()));
return ret.first->second;
}
iterator Find(const K& key) { return _ht.Find(key); }
bool Erase(const K& key) { return _ht.Erase(key); }
private:
hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT, Hash> _ht;
};
}