Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2019
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.02 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using namespace std;
  5.  
  6.  
  7. template <class KeyType, class ValueType, class Hash = std::hash<KeyType> >
  8. class HashMap {
  9. public:
  10. using KV = pair<KeyType, ValueType>;
  11.  
  12. template <class flag, class type> class add_const_if;
  13.  
  14. template <class type>
  15. class add_const_if<true_type, type> {
  16. using value = const type;
  17. };
  18.  
  19. template <class type>
  20. class add_const_if<false_type, type> {
  21. using value = type;
  22. };
  23.  
  24. template <class KV>
  25. class iter : public std::iterator<std::input_iterator_tag, KV, long, const KV*, long> {
  26. using buckets_type = add_const_if<is_const<KV>, vector<vector<KV>>>;
  27. public:
  28. iter(buckets_type &buckets): buckets(buckets) {
  29. while (bucketIndex < buckets.size() && buckets[bucketIndex].empty()) {
  30. bucketIndex++;
  31. }
  32. if (bucketIndex == buckets.size()) {
  33. bucketIndex = -1; // end
  34. valueIndex = -1;
  35. }
  36. }
  37.  
  38. iter(size_t bucketIndex, size_t valueIndex, buckets_type &buckets)
  39. : bucketIndex(bucketIndex)
  40. , valueIndex(valueIndex)
  41. , buckets(buckets) {
  42. }
  43.  
  44. KV& operator*() {
  45. return buckets[bucketIndex][valueIndex];
  46. }
  47.  
  48. // KV* operator->() {
  49. // return &buckets[bucketIndex][valueIndex];
  50. // }
  51.  
  52. iter& operator++() {
  53. if (valueIndex == buckets[bucketIndex].size() - 1) {
  54. bucketIndex++;
  55. while (bucketIndex < buckets.size() && buckets[bucketIndex].empty()) {
  56. bucketIndex++;
  57. }
  58. valueIndex = 0;
  59. if (bucketIndex == buckets.size()) {
  60. bucketIndex = -1; // end
  61. valueIndex = -1;
  62. }
  63. }
  64. else {
  65. valueIndex++;
  66. }
  67. return *this;
  68. }
  69.  
  70. iter operator++(int) {
  71. return ++*this;
  72. }
  73.  
  74. bool operator==(const iter& another) {
  75. return another.bucketIndex == bucketIndex && another.valueIndex == valueIndex;
  76. }
  77.  
  78. bool operator!=(const iter& another) {
  79. return !this->operator==(another);
  80. }
  81.  
  82. buckets_type &buckets;
  83. size_t bucketIndex = 0, valueIndex = 0;
  84. };
  85.  
  86. using iterator = iter<KV>;
  87. using const_iterator = iter<const KV>;
  88.  
  89. HashMap();
  90. HashMap(const iterator& begin, const iterator& end, const Hash& hasher = Hash()): hasher(hasher) {
  91. buckets.resize(8);
  92. for (; begin < end; begin++) {
  93. insert(*begin);
  94. }
  95. }
  96.  
  97. HashMap(const initializer_list<KV>& list, const Hash& hasher = Hash()): hasher(hasher) {
  98. buckets.resize(8);
  99. for (auto& kv : list) {
  100. insert(kv);
  101. }
  102. }
  103.  
  104. iterator begin() {
  105. return iterator(buckets);
  106. }
  107.  
  108. iterator end() {
  109. return iterator(-1, -1, buckets);
  110. }
  111.  
  112. void insert(const KV& kv) {
  113. vector<KV>& hashValues = buckets[hasher(kv.first) % buckets.size()];
  114. auto ptr = find_if(hashValues.begin(), hashValues.end(), [&kv](const KV& x) -> bool {return x.first == kv.first;});
  115. if (ptr != hashValues.end())
  116. return;
  117. hashValues.push_back(kv);
  118. sizeOfTable++;
  119. }
  120.  
  121. size_t size() const {
  122. return sizeOfTable;
  123. }
  124.  
  125. bool empty() const {
  126. return sizeOfTable == 0;
  127. }
  128.  
  129. Hash hash_function() const {
  130. return hasher;
  131. }
  132.  
  133. void erase(const KeyType& key) {
  134. size_t index = hasher(key) % buckets.size();
  135. vector<KV> hashValues = buckets[index];
  136. buckets[index].clear();
  137. copy_if(hashValues.begin(), hashValues.end(), back_inserter(buckets[index]), [&key](const KV& x) -> bool {return x.first != key;});
  138. }
  139.  
  140. ValueType& operator[](const KeyType& key) {
  141. vector<KV>& hashValues = buckets[hasher(key) % buckets.size()];
  142. auto ptr = find_if(hashValues.begin(), hashValues.end(), [&key](const KV& x) -> bool {return x.first == key;});
  143. if (ptr == hashValues.end()) {
  144. hashValues.push_back({key, ValueType()});
  145. return hashValues.back().second;
  146. }
  147. return ptr->second;
  148. }
  149. iterator find(const KeyType& key) {
  150. size_t index = hasher(key) % buckets.size();
  151. vector<KV>& hashValues = buckets[index];
  152. auto ptr = find_if(hashValues.begin(), hashValues.end(), [&key](const KV& x) -> bool {return x.first == key;});
  153. if (ptr == hashValues.end())
  154. return iterator(-1, -1, buckets);
  155. return iterator(index, ptr - hashValues.begin());
  156. }
  157. const_iterator find(const KeyType& key) const {
  158. size_t index = hasher(key) % buckets.size();
  159. const vector<KV>& hashValues = buckets[index];
  160. auto ptr = find_if(hashValues.begin(), hashValues.end(), [&key](const KV& x) -> bool {return x.first == key;});
  161. if (ptr == hashValues.end())
  162. return const_iterator(-1, -1, buckets);
  163. return const_iterator(index, ptr - hashValues.begin());
  164. }
  165.  
  166. const ValueType& at(const KeyType& key)const {
  167. const vector<KV>& hashValues = buckets[hasher(key) % buckets.size()];
  168. auto iter = find(key);
  169. if (iter == this->end()) {
  170. throw out_of_range("Key wasn't found");
  171. }
  172. return iter->second;
  173. }
  174.  
  175. void clear() {
  176. buckets.assign(8);
  177. }
  178.  
  179. vector<vector<KV>> buckets;
  180. Hash hasher;
  181. size_t sizeOfTable = 0;
  182. };
  183.  
  184.  
  185.  
  186.  
  187. int main() {
  188.  
  189. HashMap<string, int> hah({make_pair("a", 1), make_pair("b", 2)});
  190. hah["kek"] = 13;
  191. cout << hah.at("a");
  192. // for (auto x = hah.begin(); x != hah.end(); x++) {
  193. // cout << x->first << " " << x->second << "\n";
  194. // }
  195. return 0;
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement