Advertisement
playerr17

Untitled

Jan 26th, 2023
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.00 KB | None | 0 0
  1. template<class KeyType, class ValueType, class Hash = std::hash<KeyType> >
  2. class HashMap {
  3. public:
  4.     class iterator {
  5.     public:
  6.         iterator() = default;
  7.  
  8.         iterator(std::vector<std::list<std::pair<const KeyType, ValueType>>>& table, size_t index, typename std::list<std::pair<const KeyType, ValueType>>::iterator it);
  9.  
  10.         iterator& operator++();
  11.  
  12.         iterator operator++(int);
  13.  
  14.         std::pair<const KeyType, ValueType>& operator*();
  15.  
  16.         std::pair<const KeyType, ValueType>* operator->();
  17.  
  18.         bool operator==(const iterator& other) const;
  19.  
  20.         bool operator!=(const iterator& other) const;
  21.  
  22.     private:
  23.         std::vector<std::list<std::pair<const KeyType, ValueType>>>* table_;
  24.         size_t index_;
  25.         typename std::list<std::pair<const KeyType, ValueType>>::iterator it_;
  26.  
  27.     };
  28.  
  29.     class const_iterator {
  30.     public:
  31.         const_iterator() = default;
  32.  
  33.         const_iterator(const std::vector<std::list<std::pair<const KeyType, ValueType>>>& table, size_t index, typename std::list<std::pair<const KeyType, ValueType>>::const_iterator it);
  34.  
  35.         const_iterator& operator++();
  36.  
  37.         const_iterator operator++(int);
  38.  
  39.         const std::pair<const KeyType, ValueType>& operator*();
  40.  
  41.         const std::pair<const KeyType, ValueType>* operator->();
  42.  
  43.         bool operator==(const const_iterator& other) const;
  44.  
  45.         bool operator!=(const const_iterator& other) const;
  46.  
  47.     private:
  48.         const std::vector<std::list<std::pair<const KeyType, ValueType>>>* table_;
  49.         size_t index_;
  50.         typename std::list<std::pair<const KeyType, ValueType>>::const_iterator it_;
  51.  
  52.     };
  53.  
  54.     explicit HashMap(const Hash& hasher = Hash());
  55.  
  56.     template<class InputIterator>
  57.     HashMap(InputIterator begin, InputIterator end, Hash hasher = Hash());
  58.  
  59.     HashMap(std::initializer_list<std::pair<KeyType, ValueType>> list, const Hash& hasher = Hash());
  60.  
  61.     HashMap(const HashMap &other);
  62.  
  63.     HashMap &operator=(const HashMap &other);
  64.  
  65.     size_t size() const;
  66.  
  67.     bool empty() const;
  68.  
  69.     Hash hash_function() const;
  70.  
  71.     void insert(std::pair<KeyType, ValueType> element);
  72.  
  73.     void erase(KeyType key);
  74.  
  75.     iterator find(KeyType key);
  76.  
  77.     const_iterator find(KeyType key) const;
  78.  
  79.     ValueType &operator[](KeyType key);
  80.  
  81.     const ValueType &at(KeyType key) const;
  82.  
  83.     iterator begin();
  84.  
  85.     iterator end();
  86.  
  87.     const_iterator begin() const;
  88.  
  89.     const_iterator end() const;
  90.  
  91.     void clear();
  92.  
  93. private:
  94.     Hash hasher_;
  95.     size_t size_;
  96.     size_t capacity_;
  97.     std::vector<std::list<std::pair<const KeyType, ValueType>>> table_;
  98.     double load_factor_ = 0.125;  // TODO : change load factor
  99.  
  100.     void ReHash();
  101.  
  102.     void InsertElement(std::pair<KeyType, ValueType> element);
  103.  
  104.     bool IsExist(KeyType key) const;
  105.  
  106. };
  107.  
  108. template<class KeyType, class ValueType, class Hash>
  109. template<class InputIterator>
  110. HashMap<KeyType, ValueType, Hash>::HashMap(InputIterator begin, InputIterator end, Hash hasher) : hasher_(hasher),
  111.                                             size_(0), capacity_(8), table_(8) {
  112.     while (begin != end) {
  113.         insert(*begin);
  114.         begin++;
  115.     }
  116. }
  117.  
  118. template<class KeyType, class ValueType, class Hash>
  119. HashMap<KeyType, ValueType, Hash>::HashMap(const HashMap &other) : hasher_(other.hasher_),
  120.                                                                    size_(0), capacity_(other.capacity_), table_(other.capacity_)  {
  121.     hasher_ = other.hasher_;
  122.     for (auto& element : other) {
  123.         insert(element);
  124.     }
  125. }
  126.  
  127. template<class KeyType, class ValueType, class Hash>
  128. HashMap<KeyType, ValueType, Hash>::HashMap(std::initializer_list<std::pair<KeyType, ValueType>> list,
  129.                                            const Hash& hasher) : hasher_(hasher), size_(0), capacity_(8),
  130.                                            table_(8) {
  131.     for (auto &element : list) {
  132.         insert(element);
  133.     }
  134. }
  135.  
  136. template<class KeyType, class ValueType, class Hash>
  137. HashMap<KeyType, ValueType, Hash>::HashMap(const Hash& hasher) : hasher_(hasher),
  138.                                                                  size_(0), capacity_(8), table_(8) {
  139. }
  140.  
  141. template<class KeyType, class ValueType, class Hash>
  142. HashMap<KeyType, ValueType, Hash>& HashMap<KeyType, ValueType, Hash>::operator=(const HashMap &other) {
  143.     if (this == &other) {
  144.         return *this;
  145.     }
  146.     clear();
  147.     hasher_ = other.hasher_;
  148.     for (auto& element : other) {
  149.         insert(element);
  150.     }
  151.     return *this;
  152. }
  153.  
  154. template<class KeyType, class ValueType, class Hash>
  155. size_t HashMap<KeyType, ValueType, Hash>::size() const {
  156.     return size_;
  157. }
  158.  
  159. template<class KeyType, class ValueType, class Hash>
  160. bool HashMap<KeyType, ValueType, Hash>::empty() const {
  161.     return size_ == 0;
  162. }
  163.  
  164. template<class KeyType, class ValueType, class Hash>
  165. Hash HashMap<KeyType, ValueType, Hash>::hash_function() const {
  166.     return hasher_;
  167. }
  168.  
  169. template<class KeyType, class ValueType, class Hash>
  170. void HashMap<KeyType, ValueType, Hash>::insert(std::pair<KeyType, ValueType> element) {
  171.     size_t hash = hasher_(element.first) % capacity_;
  172.     if (!IsExist(element.first)) {
  173.         table_[hash].push_back(element);
  174.         size_++;
  175.         if (size_ * load_factor_ > capacity_ * 1.0) {
  176.             ReHash();
  177.         }
  178.     }
  179. }
  180.  
  181. template<class KeyType, class ValueType, class Hash>
  182. void HashMap<KeyType, ValueType, Hash>::erase(KeyType key) {
  183.     size_t hash = hasher_(key) % capacity_;
  184.     for (auto it = table_[hash].begin(); it != table_[hash].end(); it++) {
  185.         if (it->first == key) {
  186.             table_[hash].erase(it);
  187.             size_--;
  188.             return;
  189.         }
  190.     }
  191. }
  192.  
  193. template<class KeyType, class ValueType, class Hash>
  194. typename HashMap<KeyType, ValueType, Hash>::iterator HashMap<KeyType, ValueType, Hash>::find(KeyType key) {
  195.     size_t hash = hasher_(key) % capacity_;
  196.     for (auto it = table_[hash].begin(); it != table_[hash].end(); it++) {
  197.         if (it->first == key) {
  198.             return iterator(table_, hash, it);
  199.         }
  200.     }
  201.     return end();
  202. }
  203.  
  204. template<class KeyType, class ValueType, class Hash>
  205. typename HashMap<KeyType, ValueType, Hash>::const_iterator HashMap<KeyType, ValueType, Hash>::find(KeyType key) const {
  206.     size_t hash = hasher_(key) % capacity_;
  207.     for (auto it = table_[hash].begin(); it != table_[hash].end(); it++) {
  208.         if (it->first == key) {
  209.             return const_iterator(table_, hash, it);
  210.         }
  211.     }
  212.     return end();
  213. }
  214.  
  215. template<class KeyType, class ValueType, class Hash>
  216. ValueType &HashMap<KeyType, ValueType, Hash>::operator[](KeyType key) {
  217.     insert({key, ValueType()});
  218.     return find(key)->second;
  219. }
  220.  
  221. template<class KeyType, class ValueType, class Hash>
  222. const ValueType &HashMap<KeyType, ValueType, Hash>::at(KeyType key) const {
  223.     if (IsExist(key)) {
  224.         return find(key)->second;
  225.     }
  226.     throw std::out_of_range("Key not found");
  227. }
  228.  
  229. template<class KeyType, class ValueType, class Hash>
  230. typename HashMap<KeyType, ValueType, Hash>::iterator HashMap<KeyType, ValueType, Hash>::begin() {
  231.     for (size_t i = 0; i < capacity_; i++) {
  232.         if (!table_[i].empty()) {
  233.             return iterator(table_, i, table_[i].begin());
  234.         }
  235.     }
  236.     return iterator(table_, capacity_, table_[0].begin());
  237. }
  238.  
  239. template<class KeyType, class ValueType, class Hash>
  240. typename HashMap<KeyType, ValueType, Hash>::iterator HashMap<KeyType, ValueType, Hash>::end() {
  241.     return iterator(table_, capacity_, table_[0].begin());
  242. }
  243.  
  244. template<class KeyType, class ValueType, class Hash>
  245. typename HashMap<KeyType, ValueType, Hash>::const_iterator HashMap<KeyType, ValueType, Hash>::begin() const {
  246.     for (size_t i = 0; i < capacity_; i++) {
  247.         if (!table_[i].empty()) {
  248.             return const_iterator(table_, i, table_[i].begin());
  249.         }
  250.     }
  251.     return const_iterator(table_, capacity_, table_[0].begin());
  252. }
  253.  
  254. template<class KeyType, class ValueType, class Hash>
  255. typename HashMap<KeyType, ValueType, Hash>::const_iterator HashMap<KeyType, ValueType, Hash>::end() const {
  256.     return const_iterator(table_, capacity_, table_[0].begin());
  257. }
  258.  
  259. template<class KeyType, class ValueType, class Hash>
  260. void HashMap<KeyType, ValueType, Hash>::clear() {
  261.     size_ = 0;
  262.     capacity_ = 8;
  263.     table_.clear();
  264.     table_.resize(8);
  265. }
  266.  
  267. template<class KeyType, class ValueType, class Hash>
  268. void HashMap<KeyType, ValueType, Hash>::ReHash() {
  269.     auto old_table = table_;
  270.     capacity_ *= 2;
  271.     table_.clear();
  272.     table_.resize(capacity_);
  273.     for (auto &list : old_table) {
  274.         for (auto &element : list) {
  275.             InsertElement(element);
  276.         }
  277.     }
  278. }
  279.  
  280. template<class KeyType, class ValueType, class Hash>
  281. bool HashMap<KeyType, ValueType, Hash>::IsExist(KeyType key) const {
  282.     size_t hash = hasher_(key) % capacity_;
  283.     for (auto &element : table_[hash]) {
  284.         if (element.first == key) {
  285.             return true;
  286.         }
  287.     }
  288.     return false;
  289. }
  290.  
  291. template<class KeyType, class ValueType, class Hash>
  292. void HashMap<KeyType, ValueType, Hash>::InsertElement(std::pair<KeyType, ValueType> element) {
  293.     size_t hash = hasher_(element.first) % capacity_;
  294.     table_[hash].push_back(element);
  295. }
  296.  
  297. template<class KeyType, class ValueType, class Hash>
  298. HashMap<KeyType, ValueType, Hash>::iterator::iterator(
  299.         std::vector<std::list<std::pair<const KeyType, ValueType>>> &table, size_t index,
  300.         typename std::list<std::pair<const KeyType, ValueType>>::iterator it) : table_(&table), index_(index), it_(it) {}
  301.  
  302. template<class KeyType, class ValueType, class Hash>
  303. typename HashMap<KeyType, ValueType, Hash>::iterator& HashMap<KeyType, ValueType, Hash>::iterator::operator++() {
  304.     if (it_ != --table_->at(index_).end()) {
  305.         it_++;
  306.         return *this;
  307.     }
  308.     for (size_t i = index_ + 1; i < table_->size(); i++) {
  309.         if (!table_->at(i).empty()) {
  310.             index_ = i;
  311.             it_ = table_->at(i).begin();
  312.             return *this;
  313.         }
  314.     }
  315.     index_ = table_->size();
  316.     it_ = table_->at(0).begin();
  317.     return *this;
  318. }
  319.  
  320. template<class KeyType, class ValueType, class Hash>
  321. typename HashMap<KeyType, ValueType, Hash>::iterator HashMap<KeyType, ValueType, Hash>::iterator::operator++(int) {
  322.     iterator tmp = *this;
  323.     ++(*this);
  324.     return tmp;
  325. }
  326.  
  327. template<class KeyType, class ValueType, class Hash>
  328. std::pair<const KeyType, ValueType>& HashMap<KeyType, ValueType, Hash>::iterator::operator*() {
  329.     return *it_;
  330. }
  331.  
  332. template<class KeyType, class ValueType, class Hash>
  333. std::pair<const KeyType, ValueType>* HashMap<KeyType, ValueType, Hash>::iterator::operator->() {
  334.     return it_.operator->();
  335. }
  336.  
  337. template<class KeyType, class ValueType, class Hash>
  338. bool HashMap<KeyType, ValueType, Hash>::iterator::operator==(const iterator& other) const {
  339.     return table_ == other.table_ && index_ == other.index_ && it_ == other.it_;
  340. }
  341.  
  342. template<class KeyType, class ValueType, class Hash>
  343. bool HashMap<KeyType, ValueType, Hash>::iterator::operator!=(const iterator& other) const {
  344.     return !(*this == other);
  345. }
  346.  
  347. template<class KeyType, class ValueType, class Hash>
  348. HashMap<KeyType, ValueType, Hash>::const_iterator::const_iterator(
  349.         const std::vector<std::list<std::pair<const KeyType, ValueType>>>& table, size_t index,
  350.         typename std::list<std::pair<const KeyType, ValueType>>::const_iterator it) : table_(&table), index_(index), it_(it) {}
  351.  
  352. template<class KeyType, class ValueType, class Hash>
  353. typename HashMap<KeyType, ValueType, Hash>::const_iterator& HashMap<KeyType, ValueType, Hash>::const_iterator::operator++() {
  354.     if (it_ != --table_->at(index_).end()) {
  355.         it_++;
  356.         return *this;
  357.     }
  358.     for (size_t i = index_ + 1; i < table_->size(); i++) {
  359.         if (!table_->at(i).empty()) {
  360.             index_ = i;
  361.             it_ = table_->at(i).begin();
  362.             return *this;
  363.         }
  364.     }
  365.     index_ = table_->size();
  366.     it_ = table_->at(0).begin();
  367.     return *this;
  368. }
  369.  
  370. template<class KeyType, class ValueType, class Hash>
  371. typename HashMap<KeyType, ValueType, Hash>::const_iterator HashMap<KeyType, ValueType, Hash>::const_iterator::operator++(int) {
  372.     const_iterator tmp = *this;
  373.     ++(*this);
  374.     return tmp;
  375. }
  376.  
  377. template<class KeyType, class ValueType, class Hash>
  378. const std::pair<const KeyType, ValueType>& HashMap<KeyType, ValueType, Hash>::const_iterator::operator*() {
  379.     return *it_;
  380. }
  381.  
  382. template<class KeyType, class ValueType, class Hash>
  383. const std::pair<const KeyType, ValueType>* HashMap<KeyType, ValueType, Hash>::const_iterator::operator->() {
  384.     return it_.operator->();
  385. }
  386.  
  387. template<class KeyType, class ValueType, class Hash>
  388. bool HashMap<KeyType, ValueType, Hash>::const_iterator::operator==(const const_iterator& other) const {
  389.     return table_ == other.table_ && index_ == other.index_ && it_ == other.it_;
  390. }
  391.  
  392. template<class KeyType, class ValueType, class Hash>
  393. bool HashMap<KeyType, ValueType, Hash>::const_iterator::operator!=(const const_iterator& other) const {
  394.     return !(*this == other);
  395. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement