Advertisement
Guest User

Untitled

a guest
Feb 26th, 2017
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.91 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using std::vector;
  5.  
  6. #define element std::pair<const KeyType, ValueType>
  7. #define bucket std::vector<element>
  8. #define pbucket bucket*
  9.  
  10. template<class KeyType, class ValueType>
  11. class hash_iterator: public std::iterator<std::forward_iterator_tag, element> {
  12.   typedef typename vector<element>::iterator viterator;
  13.  
  14.  private:
  15.   vector<pbucket> &data_;
  16.   viterator it_;
  17.   size_t index_;
  18.  
  19.  public:
  20.   hash_iterator(const vector<pbucket> &data, const size_t ind, const viterator x) : data_(data) {
  21.     index_ = ind;
  22.     it_ = x;
  23.   }
  24.  
  25.   const element operator*(const hash_iterator &x) const {
  26.     return *x.it_;
  27.   }
  28.  
  29.   friend const hash_iterator operator++(hash_iterator &x, int) {
  30.     hash_iterator y = x;
  31.     x.it_++;
  32.     while (x.it_ == x.data_[x.index_]->end()) {
  33.       (x.index_)++;
  34.     }
  35.     return y;
  36.   }
  37.  
  38.   friend const hash_iterator& operator++(hash_iterator &x) {
  39.     ++x.it_;
  40.     while (x.it_ == x.data_[x.index_]->end()) {
  41.       ++(x.index_);
  42.     }
  43.     return x;
  44.   }
  45.  
  46. /*
  47.   const hash_iterator& operator=(const const_hash_iterator &x) : this->data_(x.data_) {
  48.     this->it_ = x.it_;
  49.     this->index_ = x.index_;
  50.   }
  51. */
  52. };
  53.  
  54. template<class KeyType, class ValueType>
  55. class const_hash_iterator: public std::iterator<std::forward_iterator_tag, element> {
  56.   typedef typename vector<element>::iterator viterator;
  57.  
  58.  private:
  59.   vector<pbucket> &data_;
  60.   viterator it_;
  61.   size_t index_;
  62.  
  63.  public:
  64.   const_hash_iterator(const vector<pbucket> &data, const size_t ind, const viterator x) {
  65.     data_(data);
  66.     index_ = ind;
  67.     it_ = x;
  68.   }
  69.  
  70.   const element operator*(const const_hash_iterator &x) const {
  71.     return *x.it_;
  72.   }
  73.  
  74.   const_hash_iterator& operator=(const hash_iterator<KeyType, ValueType> &x) {
  75.     if (this == &x)
  76.       return *this;
  77.     this->data_(x.data_);
  78.     this->it_ = x.it_;
  79.     this->index_ = x.index_;
  80.     return *this;
  81.   }
  82. };
  83.  
  84. template<class KeyType, class ValueType, class Hash = std::hash<KeyType>>
  85. class HashMap {
  86.  private:
  87.   typedef hash_iterator<const KeyType, ValueType> iterator;
  88.   typedef const_hash_iterator<const KeyType, ValueType> const_iterator;
  89.   const double LOAD_FACTOR = 0.3;
  90.  
  91.   vector<pbucket> data_;
  92.   size_t size_, tsize_;  // table size = data_.capacity()
  93.   Hash hasher;
  94.  
  95.   void data_clearing() {
  96.     for (size_t i = 0; i < data_.size(); ++i) {  // mb bug
  97.       (*data_[i]).clear();
  98.       delete (*data_[i]);
  99.     }
  100.   }
  101.  
  102.   void fix() {
  103.     if (1.0 * size_ / tsize_ < LOAD_FACTOR)
  104.       return;
  105.     iterator it = this->begin();
  106.     iterator end = this->end();
  107.     tsize_ *= 3;
  108.     vector<pbucket> buf;
  109.     buf.reserve(tsize_);
  110.     for (size_t i = 0; i < tsize_; ++i)
  111.       buf[i] = new bucket;
  112.     while (it != end) {
  113.       size_t ind = get_pos(it->first);
  114.       buf[ind]->push_back(*it);
  115.       ++it;
  116.     }
  117.     data_clearing();
  118.     data_ = buf;
  119.   }
  120.  
  121.   size_t get_pos(KeyType x) const {
  122.     return hasher(x) % tsize_;
  123.   }
  124.  
  125.   iterator find_in_bucket(size_t ind, KeyType x) const {
  126.     size_t i = 0;
  127.     for (auto it = data_[ind]->begin(); it != data_[ind]->end(); ++it, ++i) {
  128.       if (it->first == x)
  129.         return iterator(data_, ind, it);
  130.     }
  131.     return iterator(data_, ind, data_[ind]->end());
  132.   }
  133.  
  134.  public:
  135.   HashMap(const Hash& hash = Hash()) {
  136.     size_ = 0;
  137.     tsize_ = 10;
  138.     data_.reserve(10);
  139.     for (size_t i = 0; i < 10; ++i)
  140.       data_[i] = new bucket;
  141.     hasher = hash;
  142.   }
  143.  
  144.   HashMap(iterator l, iterator r, const Hash& hash = Hash()) {
  145.     (*this) = HashMap(hash);
  146.     while (l != r) {
  147.       insert((*l)++);
  148.     }
  149.   }
  150.  
  151.   HashMap(std::initializer_list<std::pair<KeyType, ValueType>> x, const Hash& hash = Hash()) {
  152.     (*this) = HashMap(hash);
  153.     for (auto it = x.begin(); it != x.end(); ++it) {
  154.       insert(*x);
  155.     }
  156.   }
  157.  
  158.   const_iterator begin() const {
  159.     return const_iterator(data_, 0, data_[0].begin());
  160.   }
  161.  
  162.   const_iterator end() const {
  163.     return const_iterator(data_, tsize_ - 1, data_[tsize_ - 1].end());
  164.   }
  165.  
  166.   iterator begin() {
  167.     return iterator(data_, 0, data_[0].begin());
  168.   }
  169.  
  170.   iterator end() {
  171.     return iterator(data_, tsize_ - 1, data_[tsize_ - 1].end());
  172.   }
  173.  
  174.   const size_t size() const {
  175.     return size_;
  176.   }
  177.  
  178.   const bool empty() const {
  179.     return !size_;
  180.   }
  181.  
  182.   const Hash& hash_function() const {
  183.     return hasher;
  184.   }
  185.  
  186.   void insert(std::pair<KeyType, ValueType> x) {
  187.     size_t ind = get_pos(x.first);
  188.     if (find_in_bucket(ind, x.first) == data_[ind]->end())
  189.       return;
  190.     (*data_[ind]).push_back(x);
  191.     ++size_;
  192.     fix();
  193.   }
  194.  
  195.   void erase(std::pair<KeyType, ValueType> x) {
  196.     size_t ind = get_pos(x.first);
  197.     iterator it = find_in_bucket(ind, x.first);
  198.     if (it == data_[ind]->end())
  199.       return;
  200.     --size_;
  201.     (*data_[ind]).erase(it);
  202.   }
  203.  
  204.   iterator find(const KeyType x) {
  205.     size_t ind = get_pos(x);
  206.     iterator it = find_in_bucket(ind, x);
  207.     if (it == data_[ind]->end())
  208.       return this->end();
  209.     return it;
  210.   }
  211.  
  212.   const_iterator find(const KeyType x) const {
  213.     size_t ind = get_pos(x);
  214.     iterator it = find_in_bucket(ind, x);
  215.     if (it == data_[ind]->end())
  216.       return this->end();
  217.     return it;
  218.   }
  219.  
  220.   ValueType& operator[](const KeyType x) const {
  221.     size_t ind = get_pos(x);
  222.     iterator it = find(x);
  223.     if (it == this->end()) {
  224.       data_[ind]->push_back(std::make_pair(x, ValueType()));
  225.       return &((*data_[ind]).back().second);
  226.     }
  227.     return &(it->second);
  228.   }
  229.  
  230.   const ValueType& at(const KeyType x) const {
  231.     size_t ind = get_pos(x);
  232.     iterator it = find(x);
  233.     if (it == this->end()) {
  234.       std::cout << "std::out_of_range\n";  // LEL
  235.     }
  236.     return &(it->second);
  237.   }
  238.  
  239.   void clear() {
  240.     data_clearing();
  241.     size_ = 0;
  242.     tsize_ = 10;
  243.     data_.reserve(10);
  244.     for (size_t i = 0; i < 10; ++i)
  245.       data_[i] = new bucket;
  246.   }
  247.  
  248.   ~HashMap() {
  249.     data_clearing();
  250.   }
  251. };
  252.  
  253. int main() {
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement