Advertisement
Guest User

Untitled

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