Advertisement
Guest User

Untitled

a guest
Feb 20th, 2018
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.43 KB | None | 0 0
  1. #include <vector>
  2. #include <list>
  3. #include <utility>
  4. #include <stdexcept>
  5.  
  6. template<class T>
  7. void copy_list(std::list<T>& list1, const std::list<T>& list2) {
  8. list1.clear();
  9. for (const T& e : list2)
  10. list1.insert(list1.end(), e);
  11. }
  12.  
  13. template<class KeyType, class ValueType, class Hash = std::hash<KeyType>>
  14. class HashMap {
  15. private:
  16. Hash hasher;
  17. std::vector<std::pair<typename std::list<std::pair<const KeyType, ValueType>>::iterator, size_t>> hash_table;
  18. std::list<std::pair<const KeyType, ValueType>> all_elements;
  19. size_t element_count;
  20. public:
  21. using iterator = typename std::list<std::pair<const KeyType, ValueType>>::iterator;
  22. using const_iterator = typename std::list<std::pair<const KeyType, ValueType>>::const_iterator;
  23.  
  24. HashMap(Hash hasher = Hash()):hasher(hasher) {}
  25.  
  26. HashMap(HashMap& other):hasher(other.hasher),
  27. hash_table(other.hash_table),
  28. all_elements(other.all_elements),
  29. element_count(other.element_count) {}
  30.  
  31. HashMap(HashMap&& other):hasher(other.hasher),
  32. hash_table(std::move(other.hash_table)),
  33. all_elements(std::move(other.all_elements)),
  34. element_count(other.element_count) { other.element_count = 0;}
  35.  
  36. HashMap& operator=(HashMap& other) {
  37. hash_table = other.hash_table;
  38. copy_list(all_elements, other.all_elements);
  39. element_count = other.element_count;
  40. return *this;
  41. }
  42.  
  43. HashMap& operator=(HashMap&& other) {
  44. hash_table = std::move(other.hash_table);
  45. all_elements = std::move(other.all_elements);
  46. element_count = other.element_count;
  47. other.element_count = 0;
  48. return *this;
  49. }
  50.  
  51. size_t size() const {
  52. return element_count;
  53. }
  54.  
  55. bool empty() const {
  56. return element_count == 0;
  57. }
  58.  
  59. Hash hash_function() const {
  60. return hasher;
  61. }
  62.  
  63. iterator begin() {
  64. return all_elements.begin();
  65. }
  66.  
  67. iterator end() {
  68. return all_elements.end();
  69. }
  70.  
  71.  
  72. const_iterator begin() const {
  73. return all_elements.begin();
  74. }
  75.  
  76. const_iterator end() const {
  77. return all_elements.end();
  78. }
  79.  
  80. void expand_table() {
  81. size_t new_size = hash_table.size() * 2 + 1;
  82. HashMap<KeyType, ValueType, Hash> new_hash_map(begin(), end(), new_size, hasher);
  83. *this = std::move(new_hash_map);
  84. //std::vector<std::pair<typename std::list<std::pair<const KeyType, ValueType>>::iterator, size_t>> new_hash_table(new_size);
  85. //auto current = all_elements.begin();
  86. //while (current != all_elements.end()) {
  87. // auto& element = *current;
  88. // size_t hash = hasher(element.first) % new_hash_table.size();
  89. // if (new_hash_table[hash].second == 0) {
  90. // new_hash_table[hash].first = all_elements.end();
  91. // }
  92. // auto new_element = all_elements.insert(new_hash_table[hash].first, element);
  93. // new_hash_table[hash].first = new_element;
  94. // ++new_hash_table[hash].second;
  95. // ++current_elements;
  96. //}
  97. //hash_table = std::move(new_hash_table);
  98. }
  99.  
  100. iterator find(KeyType key) {
  101. size_t hash = hasher(key) % hash_table.size();
  102. iterator iter = hash_table[hash].first;
  103. for (size_t i = 0; i != hash_table[hash].second; ++i, ++iter) {
  104. if (iter->first == key)
  105. return iter;
  106. }
  107. return end();
  108. }
  109.  
  110. const_iterator find(KeyType key) const {
  111. size_t hash = hasher(key) % hash_table.size();
  112. const_iterator iter = hash_table[hash].first;
  113. for (size_t i = 0; i != hash_table[hash].second; ++i, ++iter) {
  114. if (iter->first == key)
  115. return iter;
  116. }
  117. return end();
  118. }
  119.  
  120. iterator insert(const std::pair<const KeyType, ValueType>& element) {
  121. if (element_count == hash_table.size())
  122. expand_table();
  123. auto found = find(element.first);
  124. if (found != end())
  125. return found;
  126. size_t hash = hasher(element.first) % hash_table.size();
  127. if (hash_table[hash].second == 0) {
  128. hash_table[hash].first = all_elements.end();
  129. }
  130. auto new_element = all_elements.insert(hash_table[hash].first, element);
  131. hash_table[hash].first = new_element;
  132. ++hash_table[hash].second;
  133. ++element_count;
  134. return new_element;
  135. }
  136.  
  137. void erase(KeyType key) {
  138. auto found = find(key);
  139. if (found == end())
  140. return;
  141. size_t hash = hasher(key) % hash_table.size();
  142. if (found == hash_table[hash].first) {
  143. ++hash_table[hash].first;
  144. }
  145. all_elements.erase(found);
  146. --hash_table[hash].second;
  147. --element_count;
  148. }
  149.  
  150. ValueType& operator[](KeyType key) {
  151. auto found = find(key);
  152. if (found == end()) {
  153. return insert(std::pair<const KeyType, ValueType>(key, ValueType()))->second;
  154. }
  155. return found->second;
  156. }
  157.  
  158. const ValueType& at(KeyType key) const {
  159. auto found = find(key);
  160. if (found == end())
  161. throw std::out_of_range("No such element in HashMap");
  162. return found->second;
  163. }
  164.  
  165. template<class Iter>
  166. HashMap(Iter start, Iter finish, Hash hasher = Hash()) :hasher(hasher) {
  167. while (start != finish) {
  168. insert(*start);
  169. }
  170. }
  171.  
  172. template<class Iter>
  173. HashMap(Iter start, Iter finish, size_t _size, Hash hasher = Hash()) :hasher(hasher) {
  174. hash_table.resize(_size);
  175. while (start != finish) {
  176. insert(*start);
  177. ++start;
  178. }
  179. }
  180.  
  181. HashMap(std::initializer_list<std::pair<const KeyType, ValueType>> init_list, Hash hasher = Hash()) :hasher(hasher) {
  182. hash_table.resize(init_list.size());
  183. auto start = init_list.begin();
  184. while (start != init_list.end()) {
  185. insert(*start);
  186. ++start;
  187. }
  188. }
  189.  
  190. void clear() {
  191. hash_table.clear();
  192. all_elements.clear();
  193. element_count = 0;
  194. }
  195. };
  196.  
  197. //#include <iostream>
  198.  
  199. // int main() {
  200. // std::list<stconst int> kek{1,2,3,4,5,6};
  201. // std::list<const int> rek;
  202. // rek = kek;
  203.  
  204. // return 0;
  205.  
  206.  
  207. // }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement