Advertisement
Guest User

Untitled

a guest
Nov 25th, 2015
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.95 KB | None | 0 0
  1. /**
  2. @file aisdihashmap.h
  3.  
  4. AISDIHashMap and related functions interface.
  5.      
  6. @author
  7. Pawel Cichocki
  8.  
  9. @date  
  10. last revision
  11. - 2006.03.24 Pawel Cichocki: wrote it
  12.  
  13. COPYRIGHT:
  14. Copyright (c) 2006 Instytut Informatyki, Politechnika Warszawska
  15. ALL RIGHTS RESERVED
  16. *******************************************************************************/
  17. #include <iostream>
  18. #include <utility>
  19. #define SIZE 65536
  20.  
  21. /// Default keys' comparing function for AISDIHashMap - it uses
  22. /// operator== by default.
  23. /// @returns true if keys are equal, false otherwise.
  24. /// @param key1 First key to compare.
  25. /// @param key2 Second key to compare.
  26. template <class Key>  
  27. inline bool _compFunc(const Key& key1,const Key& key2)
  28. {
  29.    return (key1==key2);
  30. };
  31.  
  32. inline unsigned hashF(const std::string& m)
  33. {
  34.   // djb2
  35.   unsigned hash = 5381;
  36.   for(auto c : m)
  37.     hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
  38.   return hash & 0xFFFF;
  39. };
  40.  
  41. /// A map with a similar interface to std::map.
  42. template<class K, class V,
  43.          unsigned hashFunc(const K&),
  44.          bool compFunc(const K&,const K&)=&_compFunc<K> >
  45. class AISDIHashMap
  46. {
  47. public:
  48.    typedef K key_type;
  49.    typedef V value_type;
  50.    typedef unsigned size_type;
  51. private:
  52.  
  53.    struct Node {
  54.       std::pair <key_type, value_type> data;
  55.       unsigned hash; // hash for key
  56.       Node *next;
  57.       Node(const Node &a) : data(a.data),hash(a.hash), next(a.next) {}
  58.       Node(std::pair<K, V> d, unsigned h, Node *ptr = nullptr):
  59.          data(d), hash(h), next(ptr) {}
  60.  
  61.    };
  62.  
  63.    Node* hashtab[SIZE];
  64.    unsigned counter;
  65.  
  66. public:
  67.    AISDIHashMap(){
  68.       for(unsigned i=0; i<SIZE; ++i)
  69.          hashtab[i] = nullptr;
  70.       counter = 0;
  71.  
  72.    }
  73.    ~AISDIHashMap(){
  74.       clear();
  75.    }
  76.  
  77.    /// Coping constructor.
  78.    explicit AISDIHashMap(const AISDIHashMap<K, V, hashFunc, compFunc>& a){
  79.       counter = 0;
  80.       for(unsigned i=0; i<SIZE; ++i)
  81.          hashtab[i] = nullptr;
  82.       const_iterator end_loop = a.end();
  83.       for ( const_iterator i = a.begin(); i != end_loop; ++i)
  84.         insert(i.node->data);
  85.    }
  86.  
  87.    /// const_iterator.
  88.    class const_iterator: public std::iterator<std::forward_iterator_tag,
  89.                                               std::pair<K, V> > {
  90.       friend class AISDIHashMap;
  91.  
  92.    protected:
  93.       Node * node;
  94.       AISDIHashMap * map;
  95.    public:
  96.       typedef std::pair<K, V> T;
  97.       const_iterator() {}
  98.       const_iterator(const const_iterator& a) : node(a.node), map(a.map) {}
  99.       const_iterator(Node* n, AISDIHashMap* m): node(n), map(m) {}
  100.  
  101.         inline const T* operator*() const
  102.         {
  103.           return (T&)node->data;
  104.         }
  105.      
  106.         inline const T* operator->() const
  107.         {
  108.           return &(node->data);
  109.         }
  110.  
  111.       const_iterator& operator++() {
  112.             if( node == nullptr) return *this;
  113.             if( node->next != nullptr) {
  114.                node = node->next;
  115.                return *this;
  116.             }
  117.             //starting looking for new node but we know that it is not
  118.             //in current_index so we have to increment it when we start
  119.             unsigned current_index = node->hash + 1;
  120.             for(; current_index < SIZE; ++current_index) {
  121.                node = map->hashtab[current_index];
  122.                if (node != nullptr) break;
  123.             }
  124.             return *this;            
  125.         }
  126.        
  127.  
  128.       const_iterator operator++(int) {
  129.         const_iterator temp = *this;
  130.         ++(*this);
  131.         return temp;
  132.       }
  133.  
  134.       bool operator==(const const_iterator& a) const
  135.       {
  136.         return node == a.node;
  137.       }
  138.  
  139.       bool operator!=(const const_iterator& a) const
  140.       {
  141.         return node != a.node;
  142.       }
  143.  
  144.    };
  145.    /// iterator.
  146.    class iterator : public std::iterator<std::forward_iterator_tag,
  147.                                               std::pair<K, V> > {
  148.       friend class AISDIHashMap;
  149.       // inheritance doesnt work for these two:
  150.       Node * node;
  151.       AISDIHashMap * map;
  152.     public:
  153.       typedef std::pair<K, V> T;
  154.       iterator() {}
  155.       iterator(const iterator& a) : node(a.node), map(a.map) {}
  156.       iterator(Node* n, AISDIHashMap* m): node(n), map(m) {}
  157.  
  158.       inline T* operator*()
  159.       {
  160.           return (T&)node->data;
  161.       }
  162.      
  163.       inline T* operator->()
  164.       {
  165.           return &(node->data);
  166.       }
  167.  
  168.       iterator& operator++()   // pre
  169.       {
  170.          if( node == nullptr) return *this;
  171.          if( node->next != nullptr) {
  172.             node = node->next;
  173.             return *this;
  174.          }
  175.          //starting looking for new node but we know that it is not
  176.          //in current_index so we have to increment it when we start
  177.          unsigned current_index = node->hash + 1;
  178.          for(; current_index < SIZE; ++current_index) {
  179.             node = map->hashtab[current_index];
  180.             if (node != nullptr) break;
  181.          }
  182.          return *this;        
  183.       }
  184.  
  185.       iterator operator++(int) // post
  186.       {
  187.         iterator temp = *this;
  188.         ++*this;
  189.         return temp;
  190.       }
  191.  
  192.       bool operator==(const iterator& a)
  193.       {
  194.         return node == a.node;
  195.       }
  196.  
  197.       bool operator!=(const iterator& a)
  198.       {
  199.         return node != a.node;
  200.       }
  201.  
  202.    };
  203.  
  204.    /// Returns an iterator addressing the first element in the map.
  205.    inline iterator begin(){
  206.       Node *node = nullptr;
  207.       for(unsigned current_index = 0; current_index < SIZE; ++current_index){
  208.          node = hashtab[current_index];
  209.          if (node != nullptr) break;
  210.       }
  211.       return iterator(node, this);
  212.    }
  213.  
  214.    inline const_iterator begin() const{
  215.       Node *node = nullptr;
  216.       for(unsigned current_index = 0; current_index < SIZE; ++current_index){
  217.          node = hashtab[current_index];
  218.          if (node != nullptr) break;
  219.       }
  220.       return const_iterator(node, const_cast<AISDIHashMap*> (this));
  221.    }
  222.  
  223.    /// Returns an iterator that addresses the location succeeding the last element in a map.
  224.    inline iterator end() {
  225.      return iterator(nullptr, this);
  226.    }
  227.    inline const_iterator end() const{
  228.      return const_iterator(nullptr, const_cast<AISDIHashMap*> (this) );
  229.    }
  230.    
  231.    /// Inserts an element into the map.
  232.    /// @returns A pair whose bool component is true if an insertion was
  233.    ///          made and false if the map already contained an element
  234.    ///          associated with that key, and whose iterator component coresponds to
  235.    ///          the address where a new element was inserted or where the element
  236.    ///          was already located.
  237.    std::pair<iterator, bool> insert(const std::pair<K, V>& entry) {
  238.       unsigned entry_hash = hashFunc(entry.first);
  239.  
  240.       if ( hashtab[entry_hash] == nullptr ) {
  241.          hashtab[entry_hash] = new Node(entry, entry_hash, nullptr);
  242.          ++counter;
  243.          return std::make_pair(iterator(hashtab[entry_hash], this), true);
  244.       }
  245.  
  246.       iterator i = find(entry.first);
  247.  
  248.       if( i != end())
  249.          return std::make_pair(i, false);
  250.  
  251.       Node *curr = hashtab[entry_hash];
  252.       while (curr->next != nullptr)
  253.          curr = curr->next;
  254.       curr->next = new Node(entry, entry_hash);
  255.       ++counter;
  256.       return std::make_pair(iterator(curr->next, this), true);
  257.  
  258.    }
  259.  
  260.    /// Returns an iterator addressing the location of the entry in the map
  261.    /// that has a key equivalent to the specified one or the location succeeding the
  262.    /// last element in the map if there is no match for the key.
  263.    iterator find(const K& k) {
  264.       Node *ptr = hashtab[hashFunc(k)];
  265.       if( ptr == nullptr) return end();
  266.       while (ptr != nullptr) {
  267.          if (compFunc(ptr->data.first, k) ) return iterator(ptr, this);
  268.          ptr = ptr->next;
  269.       }
  270.       return end();
  271.    }
  272.  
  273.    /// Returns an const iterator
  274.    const_iterator find(const K& k) const {
  275.        Node *ptr = hashtab[hashFunc(k)];
  276.        if (ptr == nullptr) return end();
  277.        while (ptr != nullptr) {
  278.          if (compFunc(ptr->data.first, k) ) return const_iterator(ptr,
  279.                                        const_cast<AISDIHashMap*>(this));
  280.          ptr = ptr->next;
  281.        }
  282.        return end();
  283.    }
  284.  
  285.    /// Inserts an element into a map with a specified key value
  286.    /// if one with such a key value does not exist.
  287.    /// @returns Reference to the value component of the element defined by the key.
  288.    V& operator[](const K& k) {
  289.  
  290.       std::pair<iterator, bool> temp = insert ( std::make_pair (k, V() ) );  
  291.       return temp.first.node->data.second;
  292.    }  
  293.  
  294.    /// Tests if a map is empty.
  295.    bool empty( ) const {
  296.     return static_cast<bool>(counter); //Casting count_ to bool. Only if
  297.    }                                  // was 0 it will return false
  298.    
  299.  
  300.    /// Returns the number of elements in the map.
  301.    size_type size() const {
  302.     return counter;
  303.    }
  304.  
  305.    /// Returns the number of elements in a map whose key matches a parameter-specified key.
  306.    size_type count(const K& _Key) const {
  307.     return (find(_Key) == end() ) ? 0 : 1; // if element found return 1  else return 0
  308.    }
  309.  
  310.    /// Removes an element from the map.
  311.    /// @returns The iterator that designates the first element remaining beyond any elements removed.
  312.    iterator erase(iterator i){
  313.       if (i.node == nullptr) return iterator(nullptr, this);
  314.  
  315.       iterator to_return = i;
  316.       ++to_return;
  317.  
  318.       unsigned elem_hash = i.node->hash;
  319.       Node *to_delete = i.node;
  320.       if (hashtab[elem_hash] == to_delete) {
  321.          hashtab[elem_hash] = to_delete->next;
  322.          delete to_delete;
  323.          --counter;
  324.          return to_return;
  325.       }
  326.       else {
  327.          Node *curr = hashtab[elem_hash];
  328.          while (curr -> next!= to_delete ) {
  329.             curr = curr->next;
  330.          }
  331.          to_delete = curr->next;
  332.          curr->next = to_delete->next;
  333.          delete to_delete;
  334.          --counter;
  335.          return to_return;
  336.       }
  337.    }
  338.    /// Removes a range of elements from the map.
  339.    /// The range is defined by the key values of the first and last iterators
  340.    /// first is the first element removed and last is the element just beyond the last elemnt removed.
  341.    /// @returns The iterator that designates the first element remaining beyond any elements removed.
  342.    iterator erase(iterator f, iterator l) {
  343.     for (; f != l && f.node != nullptr; ++f) // extra condition to avoid
  344.       erase (f);                             // deleting not in order
  345.     return l;  
  346.   }
  347.    
  348.    /// Removes an element from the map.
  349.    /// @returns The number of elements that have been removed from the map.
  350.    ///          Since this is not a multimap itshould be 1 or 0.
  351.    size_type erase(const K& key) {
  352.     iterator i = find(key);
  353.     if( i != end() ) {
  354.       erase(i);
  355.       return 1;
  356.     }
  357.     return 0;
  358.   }
  359.  
  360.    /// Erases all the elements of a map.
  361.    void clear() {
  362.     //erase ( begin(), end() );
  363.       iterator temp = begin();
  364.       while ( temp != end())
  365.          erase(temp++);
  366.    }
  367. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement