Advertisement
Guest User

Untitled

a guest
Nov 16th, 2018
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.56 KB | None | 0 0
  1. #ifndef HASH_TABLE_HASHSET_H
  2. #define HASH_TABLE_HASHSET_H
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <iterator>
  7. #include <list>
  8.  
  9. template <typename ValueType, typename KeyType, typename Hash>
  10. class HashSetIterator;
  11.  
  12. template <typename ValueType, typename KeyType, typename Hash>
  13. class HashSet {
  14.     using iterator = HashSetIterator<ValueType, KeyType, Hash>;
  15.     using const_iterator = HashSetIterator<const ValueType, const KeyType, const Hash>;
  16.  
  17.     friend class HashSetIterator<ValueType, KeyType, Hash>;
  18.  
  19. private:
  20.     std::vector<std::list<std::pair<KeyType, ValueType>>> HashTable;
  21.     unsigned int hashTableCapacity;
  22.     unsigned int used;
  23.  
  24.     unsigned int hashToIndex (KeyType key);
  25.  
  26. public:
  27.     HashSet();
  28.     explicit HashSet(unsigned int size);
  29.     HashSet(const HashSet &) = default;
  30.     ~HashSet() = default;
  31.  
  32.     HashSetIterator<ValueType, KeyType, Hash> insert(ValueType value);
  33.  
  34.     HashSetIterator<ValueType, KeyType, Hash> begin();
  35.  
  36.     unsigned int size() const;
  37.     unsigned int capacity() const;
  38.     bool empty() const;
  39.     double fillFactor() const;
  40. };
  41.  
  42.  
  43. // iterator
  44. template <typename ValueType, typename KeyType, typename Hash>
  45. class HashSetIterator : std::iterator<std::bidirectional_iterator_tag, std::pair<KeyType, ValueType>>{
  46.     friend class HashSet<ValueType, KeyType, Hash>;
  47.  
  48. private:
  49.     HashSet<ValueType, KeyType, Hash> * from;
  50.     unsigned int line;
  51.     typename std::list<std::pair<KeyType, ValueType>>::iterator position;
  52.  
  53. public:
  54.     HashSetIterator(HashSet<ValueType, KeyType, Hash> & from, unsigned int line,
  55.                     typename std::list<std::pair<KeyType, ValueType>>::iterator position);
  56.     explicit HashSetIterator(HashSet<ValueType, KeyType, Hash> & it);
  57.     HashSetIterator(const HashSetIterator &) = default;
  58.     ~HashSetIterator() = default;
  59.  
  60.     HashSetIterator& operator=(const HashSetIterator &) = default;
  61.     bool operator!=(HashSetIterator & other) const;
  62.     bool operator==(HashSetIterator & other) const;
  63.     std::pair<KeyType, ValueType> & operator * ();
  64.     HashSetIterator &operator++();
  65.     HashSetIterator &operator--();
  66. };
  67.  
  68. template <typename ValueType, typename KeyType, typename Hash>
  69. HashSetIterator<ValueType, KeyType, Hash>::HashSetIterator(
  70.         HashSet<ValueType, KeyType, Hash> & from, unsigned int line,
  71.         typename std::list<std::pair<KeyType, ValueType>>::iterator position) {
  72.     this->from = &from;
  73.     this->line = line;
  74.     this->position = position;
  75. }
  76.  
  77. template <typename ValueType, typename KeyType, typename Hash>
  78. HashSetIterator<ValueType, KeyType, Hash>::HashSetIterator(HashSet<ValueType, KeyType, Hash> &it) {
  79.     from = &it;
  80.  
  81.     for(unsigned int i = 0; i < it.capacity(); ++i) {
  82.         if (!it.HashTable[i].empty()) {
  83.             line = i;
  84.             position = from->HashTable[i].begin();
  85.             return;
  86.         }
  87.     }
  88.  
  89.     line = it.hashTableCapacity;
  90. }
  91.  
  92. template <typename ValueType, typename KeyType, typename Hash>
  93. bool HashSetIterator<ValueType, KeyType, Hash>::operator==(HashSetIterator &other) const {
  94.     if(line == other.line)
  95.         return (position == other.position);
  96.     else
  97.         return false;
  98. }
  99.  
  100. template <typename ValueType, typename KeyType, typename Hash>
  101. bool HashSetIterator<ValueType, KeyType, Hash>::operator!=(HashSetIterator &other) const {
  102.     if(line == other.line)
  103.         return position != other.position;
  104.     else
  105.         return false;
  106. }
  107.  
  108. template <typename ValueType, typename KeyType, typename Hash>
  109. std::pair<KeyType, ValueType>& HashSetIterator<ValueType, KeyType, Hash>::operator*(){
  110.     return *position;
  111. }
  112.  
  113. template <typename ValueType, typename KeyType, typename Hash>
  114. HashSetIterator<ValueType, KeyType, Hash>& HashSetIterator<ValueType, KeyType, Hash>::operator++() {
  115.     if(*position == from->HashTable[line].back()){
  116.         if(line == from->hashTableCapacity)
  117.             ++line;
  118.         else{
  119.             unsigned int i;
  120.             for(i = line + 1; i < from->hashTableCapacity; ++i){
  121.                 if(!from->HashTable[i].empty()) {
  122.                     position = from->HashTable[i].begin();
  123.                     line = i;
  124.                     break;
  125.                 }}
  126.  
  127.             if(line != i)
  128.                 line = from->hashTableCapacity + 1;
  129.         }
  130.     } else
  131.         ++position;
  132.  
  133.     return *this;
  134. }
  135.  
  136. template <typename ValueType, typename KeyType, typename Hash>
  137. HashSetIterator<ValueType, KeyType, Hash>& HashSetIterator<ValueType, KeyType, Hash>::operator--() {
  138.     if(*position == from->HashTable[line].front()){
  139.         if(!line)
  140.             --line;
  141.         else{
  142.             unsigned int i;
  143.             for(i = line - 1; i >= 0; --i){
  144.                 if(!from->HashTable[i].empty()) {
  145.                     position = from->HashTable[i].begin();
  146.                     line = i;
  147.                     break;
  148.                 }}
  149.  
  150.             if(line != i)
  151.                 line = -1;
  152.         }
  153.     } else
  154.         --position;
  155.  
  156.     return *this;
  157. }
  158.  
  159.  
  160. // constructors
  161. template <typename ValueType, typename KeyType, typename Hash>
  162. HashSet<ValueType, KeyType, Hash>::HashSet() {
  163.     HashTable.resize(0);
  164.     hashTableCapacity = (unsigned int)0;
  165.     used = 0;
  166. }
  167.  
  168. template <typename ValueType, typename KeyType, typename Hash>
  169. HashSet<ValueType, KeyType, Hash>::HashSet(unsigned int size) {
  170.     HashTable.resize(size, std::list<std::pair<KeyType, ValueType>> ());
  171.     hashTableCapacity = size;
  172.     used = 0;
  173. }
  174.  
  175.  
  176. // hash
  177. template <typename ValueType, typename KeyType, typename Hash>
  178. unsigned int HashSet<ValueType, KeyType, Hash>::hashToIndex(KeyType key) {
  179.     if(key > 0) // must be competatible
  180.         return (unsigned int) key % capacity();
  181.     else
  182.         return (unsigned int) (-key) % capacity();
  183. }
  184.  
  185.  
  186. // operations
  187. template <typename ValueType, typename KeyType, typename Hash>
  188. HashSetIterator<ValueType, KeyType, Hash> HashSet<ValueType, KeyType, Hash>::insert(ValueType value) {
  189.     KeyType tempKey = Hash(value);
  190.     unsigned int line = hashToIndex(tempKey);
  191.  
  192.     std::pair<KeyType, ValueType> insertion = std::make_pair(tempKey, value);
  193.  
  194.     if(HashTable[line].empty()){
  195.         HashTable[line].push_front(insertion);
  196.         return HashSetIterator<ValueType, KeyType, Hash> (*this, line, HashTable[line].begin());
  197.     }
  198.  
  199.     typename std::list<std::pair<KeyType, ValueType>>::iterator liner;
  200.     for(liner = HashTable[line].begin(); liner != HashTable[line].end(); ++liner){
  201.         if(*liner == insertion)
  202.             return HashSetIterator<ValueType, KeyType, Hash> (*this, line, liner);
  203.     }
  204.  
  205.     HashTable[line].push_front(insertion);
  206.     return HashSetIterator<ValueType, KeyType, Hash> (*this, line, HashTable[line].begin());
  207. }
  208.  
  209.  
  210. // access
  211. template <typename ValueType, typename KeyType, typename Hash>
  212. HashSetIterator<ValueType, KeyType, Hash> HashSet<ValueType, KeyType, Hash>::begin() {
  213.     return HashSetIterator<ValueType, KeyType, Hash> (*this);
  214. }
  215.  
  216.  
  217. // statistic
  218. template <typename ValueType, typename KeyType, typename Hash>
  219. unsigned int HashSet<ValueType, KeyType, Hash>::size() const{
  220.     return used;
  221. }
  222.  
  223. template <typename ValueType, typename KeyType, typename Hash>
  224. unsigned int HashSet<ValueType, KeyType, Hash>::capacity() const{
  225.     return hashTableCapacity;
  226. }
  227.  
  228. template <typename ValueType, typename KeyType, typename Hash>
  229. bool HashSet<ValueType, KeyType, Hash>::empty() const{
  230.     return !used;
  231. }
  232.  
  233. template <typename ValueType, typename KeyType, typename Hash>
  234. double HashSet<ValueType, KeyType, Hash>::fillFactor() const{
  235.     return hashTableCapacity ? used * 1.0/hashTableCapacity : 1;
  236. }
  237.  
  238. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement