Advertisement
Nickpips

HashSet

Dec 13th, 2017
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.00 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. template<typename T>
  6. class set {
  7. public:
  8.   set(size_t (*hash)(const T&), double load_factor = 0.75) {
  9.     m_hash = hash;
  10.     m_elems = 0;
  11.     m_capacity = 0;
  12.     m_buckets = nullptr;
  13.     m_load_factor = load_factor;
  14.   }
  15.   ~set() {
  16.     clear();
  17.   }
  18.   size_t size() {
  19.     return m_elems;
  20.   }
  21.   void insert(T elem) {
  22.     if( m_capacity == 0 )
  23.       ensure(1/m_load_factor + 1);
  24.     int h = m_hash(elem) % m_capacity;
  25.     node* start = m_buckets[h];
  26.     if( start == nullptr ) {
  27.       m_buckets[h] = new node;
  28.       m_buckets[h]->value = elem;
  29.       m_buckets[h]->next = nullptr;
  30.     } else {
  31.       while( start->next != nullptr ) {
  32.         if( start->value == elem )
  33.           return;
  34.         start = start->next;
  35.       }
  36.       if( start->value == elem )
  37.         return;
  38.       start->next = new node;
  39.       start = start->next;
  40.       start->value = elem;
  41.       start->next = nullptr;
  42.     }
  43.     m_elems++;
  44.     cout << "Inserting " << m_elems << "th element: " << elem << " (hash: " << h << ")" << endl;
  45.     if( m_elems > m_load_factor * m_capacity ) {
  46.       ensure(m_capacity << 1);
  47.     }
  48.   }
  49.   bool contains(T elem) {
  50.     int h = m_hash(elem) % m_capacity;
  51.     node* start = m_buckets[h];
  52.     while( start != nullptr ) {
  53.       if( start->value == elem ) {
  54.         cout << "Contains " << elem << endl;
  55.         return true;
  56.       }
  57.       start = start->next;
  58.     }
  59.     cout << "Does not contain " << elem << endl;
  60.     return false;
  61.   }
  62.   void erase(T elem) {
  63.     int h = m_hash(elem) % m_capacity;
  64.     node* prev = m_buckets[h];
  65.     node* start = m_buckets[h];
  66.     while( start != nullptr ) {
  67.       if( start->value == elem ) {
  68.         if( prev == start ) {
  69.           m_buckets[h] = start->next;
  70.         } else {
  71.           prev->next = start->next;
  72.         }
  73.         delete start;
  74.         cout << "Removing " << m_elems << "th element: " << elem << " (hash: " << h << ")" << endl;
  75.         m_elems--;
  76.         return;
  77.       }
  78.       prev = start;
  79.       start = start->next;
  80.     }
  81.   }
  82.   void clear() {
  83.     m_elems = 0;
  84.     m_capacity = 0;
  85.     if( m_buckets != nullptr ) {
  86.       for( size_t i = 0; i < m_capacity; ++i ) {
  87.         node* start = m_buckets[i];
  88.         while( start != nullptr ) {
  89.           node* del = start;
  90.           start = start->next;
  91.           delete del;
  92.         }
  93.       }
  94.       delete[] m_buckets;
  95.       m_buckets = nullptr;
  96.     }
  97.   }
  98. private:
  99.   struct node {
  100.     T value;
  101.     node* next;
  102.   };
  103.  
  104.   node** m_buckets;
  105.   size_t m_capacity;
  106.   size_t m_elems;
  107.   double m_load_factor;
  108.  
  109.   size_t (*m_hash)(const T&);
  110.  
  111.   void ensure(size_t size) {
  112.     if( size <= m_capacity )
  113.       return;
  114.     cout << "Resize to: " << size << endl;
  115.     node** old_buckets = m_buckets;
  116.     int old_capacity = m_capacity;
  117.    
  118.     m_elems = 0;
  119.     m_capacity = size;
  120.     m_buckets = new node*[m_capacity];
  121.     for( size_t i = 0; i < m_capacity; ++i ) {
  122.       m_buckets[i] = nullptr;
  123.     }
  124.     for( size_t i = 0; i < old_capacity; ++i ) {
  125.       node* start = old_buckets[i];
  126.       while( start != nullptr ) {
  127.         insert(start->value);
  128.         start = start->next;
  129.       }
  130.     }
  131.     if( old_buckets != nullptr ) {
  132.       for( size_t i = 0; i < old_capacity; ++i ) {
  133.         node* start = old_buckets[i];
  134.         while( start != nullptr ) {
  135.           node* del = start;
  136.           start = start->next;
  137.           delete del;
  138.         }
  139.       }
  140.       delete[] old_buckets;
  141.     }
  142.   }
  143. };
  144.  
  145. int main() {
  146.   set<int> vals([](const int& a) -> size_t {
  147.     return a;
  148.   } );
  149.  
  150.   vals.insert(5);
  151.   vals.insert(5);
  152.   vals.insert(2);
  153.   vals.insert(102);
  154.   vals.insert(2);
  155.   vals.insert(102);
  156.  
  157.   vals.contains(2);
  158.   vals.contains(23);
  159.   vals.contains(5);
  160.   vals.contains(102);
  161.   vals.contains(202);
  162.  
  163.   vals.erase(102);
  164.   vals.erase(5);
  165.  
  166.   vals.contains(2);
  167.   vals.contains(5);
  168.   vals.contains(102);
  169.   vals.contains(202);
  170.  
  171.   vals.clear();
  172.  
  173.   vals.insert(1);
  174.   vals.contains(1);
  175.   vals.contains(2);
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement