Advertisement
Guest User

Untitled

a guest
Apr 30th, 2016
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.03 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <list>
  4. #include <utility>
  5. #include <initializer_list>
  6.  
  7.  
  8. template<class KeyType, class ValueType>
  9. class Cell {
  10. public:
  11.     typedef std::pair<const KeyType, ValueType& > Pair;
  12.     KeyType key;
  13.     ValueType value;
  14.     Pair pair;
  15.     typename std::list<std::pair<const KeyType, ValueType& >>::iterator iterPointer; //  pointer to this cell but in iterList
  16.     Cell() {};
  17.     Cell(KeyType inputKey, ValueType inputValue):
  18.             key(inputKey),
  19.             value(inputValue),
  20.             pair(inputKey, value) {}
  21.     Cell(std::pair<const KeyType, ValueType> inputPair):
  22.             key(inputPair.first),
  23.             value(inputPair.second),
  24.             pair(inputPair) {}
  25. };
  26.  
  27. template<class KeyType, class ValueType>
  28. bool operator== (const Cell<KeyType, ValueType>& cellA, const Cell<KeyType, ValueType>& cellB) {
  29.     return cellA.key == cellB.key && cellA.key == cellB.value;
  30. }
  31.  
  32. template<class KeyType, class ValueType, class Hash = std::hash<KeyType> >
  33. class HashMap {
  34. private:
  35.     typedef Cell<const KeyType, ValueType> HashCell;
  36.     typedef std::pair<const KeyType, ValueType> Pair;
  37.     std::list<Pair> iterList;
  38.     std::list<size_t> indexList;
  39.     const size_t tableSize = 10*10*10*10*10*10;
  40.     size_t elemsNum;
  41.     size_t hashFunc(size_t num) const {
  42.         return num % tableSize;
  43.     }
  44.     Hash hasher;
  45.     std::vector<std::list<HashCell>> data;
  46.  
  47. public:
  48.     typedef typename std::list<Pair>::iterator iterator;
  49.     typedef typename std::list<Pair>::const_iterator const_iterator;
  50.     void insert(Pair input) {
  51.         HashCell cell(input);
  52.         KeyType key = cell.key;
  53.         size_t index = hashFunc(hasher(key));
  54.         ++elemsNum;
  55.         for (HashCell& bucketCell : data[index]) {
  56.             if (bucketCell.key == key) {
  57.                 return;
  58.             }
  59.         }
  60.         data[index].push_back(cell);
  61.         data[index].back().iterPointer = iterList.insert(iterList.end(), cell.pair);
  62.         //data[index].back().iterPointer = iter;
  63.         iterList.back().second = cell.value;
  64.     }
  65.  
  66.     HashMap(Hash hasher = Hash()):
  67.             data(tableSize),
  68.             hasher(hasher),
  69.             elemsNum(0) {}
  70.     template <class InputIt>
  71.     HashMap(InputIt begin,
  72.             InputIt end,
  73.             const Hash hasher = Hash()):
  74.             data(tableSize),
  75.             hasher(hasher),
  76.             elemsNum(0)
  77.     {
  78.         for ( ; begin != end; ++begin ) {
  79.             insert(*begin);
  80.         }
  81.     }
  82.  
  83.     HashMap(std::initializer_list<std::pair<const KeyType, ValueType>> input,
  84.             const Hash hasher = Hash()):
  85.             data(tableSize),
  86.             hasher(hasher),
  87.             elemsNum(0)
  88.     {
  89.         for (auto& pair : input) {
  90.             insert(pair);
  91.         }
  92.     }
  93.  
  94.     void erase(KeyType key) {
  95.         size_t index = hashFunc(hasher(key));
  96.         for (HashCell& cell : data[index]) {
  97.             if (cell.key == key) {
  98.                 --elemsNum;
  99.                 iterList.erase(cell.iterPointer); // удаление из списка итераторов
  100.                 data[index].remove(cell); // удаление из HashMap
  101.                 break;
  102.             }
  103.         }
  104.     }
  105.  
  106.     bool empty() const {
  107.         return (elemsNum == 0);
  108.     }
  109.  
  110.     size_t size() const {
  111.         return elemsNum;
  112.     }
  113.  
  114.     typename std::list<Pair>::iterator begin() {
  115.         return iterList.begin();
  116.     }
  117.  
  118.     typename std::list<Pair>::iterator end() {
  119.         return iterList.end();
  120.     }
  121.  
  122.     typename std::list<Pair>::const_iterator begin() const {
  123.         return iterList.cbegin();
  124.     }
  125.  
  126.     typename std::list<Pair>::const_iterator end() const {
  127.         return iterList.cend();
  128.     }
  129.  
  130.     Hash hash_function() const {
  131.          return hasher;
  132.     }
  133.  
  134.     typename std::list<Pair>::iterator find(KeyType key) {
  135.         size_t index = hashFunc(hasher(key));
  136.         for (HashCell& cell : data[index]) {
  137.             if (cell.key == key) {
  138.                 return cell.iterPointer;
  139.             }
  140.         }
  141.         return (*this).end();
  142.     }
  143.  
  144.     typename std::list<Pair>::const_iterator find(KeyType key) const {
  145.         size_t index = hashFunc(hasher(key));
  146.         for (HashCell cell : data[index]) {
  147.             if (cell.key == key) {
  148.                 return static_cast<typename std::list<Pair>::const_iterator>(cell.iterPointer);
  149.             }
  150.         }
  151.         return (*this).end();
  152.     }
  153.     ValueType& operator[] (KeyType key) {
  154.         size_t index = hashFunc(hasher(key));
  155.         for (HashCell &cell : data[index]) {
  156.             if (cell.key == key) {
  157.                 return cell.value;
  158.             }
  159.         }
  160.         HashCell cell(key, ValueType());
  161.  
  162.         ++elemsNum;
  163.         data[index].push_back(cell);
  164.         auto iter = iterList.insert(iterList.end(), cell.pair);
  165.         data[index].back().iterPointer = iter;
  166.         return data[index].back().value;
  167.     }
  168.  
  169.     const ValueType& at(KeyType key) const {
  170.         size_t index = hashFunc(hasher(key));
  171.         for (auto iter = data[index].begin(); iter != data[index].end(); ++iter) {
  172.             if (iter->key == key) {
  173.                 return iter->value;
  174.             }
  175.         }
  176.         throw;
  177.     }
  178.  
  179.     void clear() {
  180.         for (Pair& pair : iterList) {
  181.             KeyType key = pair.first;
  182.             size_t index = hashFunc(hasher(key));
  183.             data[index].clear();
  184.         }
  185.         iterList.clear();
  186.         elemsNum = 0;
  187.     }
  188. };
  189.  
  190.  
  191. typedef std::pair<const int, int> Pair;
  192. int main() {
  193.     HashMap<int, int> test1({Pair(1,1),Pair(2,2), Pair(3,3)});
  194.     test1.insert(Pair(4,2));
  195.     test1.insert(Pair(4,0));
  196.     test1.erase(1);
  197.     test1.insert(Pair(7,22));
  198.     test1.erase(3);
  199.     std::cout << test1.empty() << std::endl;
  200.     std::cout<< test1.size() << std::endl;
  201.     std::cout << (test1.find(3) == test1.end()) << std::endl;
  202.     std::cout << (test1.find(4) == test1.end()) << std::endl;
  203.     test1[4] = 4;
  204.     test1[6] = 8;
  205.     test1.clear();
  206.  
  207.     std::vector<Pair> input = { Pair(2, 7), Pair(3, 8) };
  208.     const HashMap<int, int> test2(input.begin(), input.end());
  209.     std::cout << test2.empty() << std::endl;
  210.     std::cout<< test2.size() << std::endl;
  211.     std::cout << (test2.find(3) == test2.end()) << std::endl;
  212.     std::cout << (test2.find(4) == test2.end()) << std::endl;
  213.     std::cout << test2.at(2) << std::endl;
  214.     //std::cout << test2.at(5) << std::endl;
  215.  
  216.     HashMap<int, int> test3;
  217.     test3[3] = 5;
  218.     test3[2] = 1;
  219.     test3[0] = 7;
  220.     std::cout << (test3.find(0) == test3.end()) << std::endl;
  221.     test3.erase(0);
  222.     std::cout << (test3.find(0) == test3.end()) << std::endl;
  223.     std::cout << (test3.find(2) == test3.end()) << std::endl;
  224.     test3[8] = -4;
  225.     for (auto iter = test3.begin(); iter != test3.end(); ++iter) {
  226.         std::cout << iter->first << " " << iter->second << std::endl;
  227.     }
  228.     test3.clear();
  229.     std::cout << (test3.find(3) == test3.end()) << std::endl;
  230.     test3[3] = 3;
  231.     std::cout << (test3.find(3) == test3.end()) << std::endl;
  232.     return 0;
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement