Advertisement
Guest User

Untitled

a guest
May 24th, 2015
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.82 KB | None | 0 0
  1. // HashSet.hpp
  2. //
  3. // ICS 46 Spring 2015
  4. // Project #3: Set the Controls for the Heart of the Sun
  5. //
  6. // A HashSet is an implementation of a Set that is a separately-chained
  7. // hash table, implemented as a dynamically-allocated array of linked
  8. // lists. At any given time, the HashSet has a "size" indicating
  9. // how many elements are stored within it, along with a "capacity"
  10. // indicating the size of the array.
  11. //
  12. // As elements are added to the HashSet and the proportion of the HashSet's
  13. // size to its capacity exceeds 0.8 (i.e., there are more than 80% as many
  14. // elements as there are array cells), the HashSet should be resized so
  15. // that it is twice as large as it was before.
  16. //
  17. // You are not permitted to use the containers in the C++ Standard Library
  18. // (such as std::vector, std::list, or std::array). Instead, you'll need
  19. // to use a dynamically-allocated array and your own linked list
  20. // implementation; the linked list doesn't have to be its own class,
  21. // though you can do that, if you'd like.
  22.  
  23. #ifndef HASHSET_HPP
  24. #define HASHSET_HPP
  25.  
  26. #include <functional>
  27. #include "Set.hpp"
  28.  
  29.  
  30.  
  31. template <typename T>
  32. class HashSet : public Set<T>
  33. {
  34. public:
  35. // The default capacity of the HashSet before anything has been
  36. // added to it.
  37. static constexpr unsigned int DEFAULT_CAPACITY = 10;
  38.  
  39. // A HashFunction
  40. typedef std::function<unsigned int(const T&)> HashFunction;
  41.  
  42. public:
  43. // Initializes a HashSet to be empty, so that it will use the given
  44. // hash function whenever it needs to hash an element.
  45. HashSet(HashFunction hashFunction);
  46.  
  47. // Cleans up the HashSet so that it leaks no memory.
  48. virtual ~HashSet();
  49.  
  50. // Initializes a new HashSet to be a copy of an existing one.
  51. HashSet(const HashSet& s);
  52.  
  53. // Assigns an existing HashSet into another.
  54. HashSet& operator=(const HashSet& s);
  55.  
  56.  
  57. // isImplemented() should be modified to return true if you've
  58. // decided to implement a HashSet, false otherwise.
  59. virtual bool isImplemented() const;
  60.  
  61.  
  62. // add() adds an element to the set. If the element is already in the set,
  63. // this function has no effect. This function triggers a resizing of the
  64. // array when the ratio of size to capacity would exceed 0.8. In the case
  65. // where the array is resized, this function runs in linear time (with
  66. // respect to the number of elements, assuming a good hash function);
  67. // otherwise, it runs in constant time (again, assuming a good hash
  68. // function).
  69. virtual void add(const T& element);
  70.  
  71.  
  72. // contains() returns true if the given element is already in the set,
  73. // false otherwise. This function runs in constant time (with respect
  74. // to the number of elements, assuming a good hash function).
  75. virtual bool contains(const T& element) const;
  76.  
  77.  
  78. // size() returns the number of elements in the set.
  79. virtual unsigned int size() const;
  80.  
  81. struct elementLink{
  82. T item;
  83. T name;
  84. elementLink* next;
  85. };
  86.  
  87. private:
  88. HashFunction hashFunction;
  89.  
  90. //lam
  91. unsigned int currentCap;
  92. elementLink** storage; //array that stores pointer to elementLink
  93. void resize(); //resize storage
  94.  
  95.  
  96. };
  97.  
  98. template <typename T>
  99. int HashSet<T>::counter = 0;
  100.  
  101. template <typename T>
  102. HashSet<T>::HashSet(HashFunction hashFunction)
  103. : hashFunction{hashFunction}
  104. {
  105. //lam
  106. currentCap = DEFAULT_CAPACITY;
  107. storage = new elementLink*[currentCap];
  108. }
  109.  
  110.  
  111. template <typename T>
  112. HashSet<T>::~HashSet()
  113. {
  114. delete hashTable[];
  115. }
  116.  
  117.  
  118. template <typename T>
  119. HashSet<T>::HashSet(const HashSet& s)
  120. : hashFunction{s.hashFunction}
  121. {
  122. currentCap = s.currentCap;
  123. storage = s.storage;
  124. }
  125.  
  126.  
  127. template <typename T>
  128. HashSet<T>& HashSet<T>::operator=(const HashSet& s)
  129. {
  130. if (this != &s)
  131. {
  132. hashFunction = s.hashFunction;
  133. }
  134.  
  135. return *this;
  136. }
  137.  
  138.  
  139. template <typename T>
  140. bool HashSet<T>::isImplemented() const
  141. {
  142. return false;
  143. }
  144.  
  145.  
  146. template <typename T>
  147. void HashSet<T>::add(const T& element)
  148. {
  149. //lam
  150. unsigned int hashResult = hashFunction(element);
  151. if(storage[hashResult] != NULL) //something is there already
  152. {
  153. if(contains(element)) //the same one
  154. {
  155. return; //nothing happen
  156. }
  157. else //not the same
  158. {
  159. resize();
  160.  
  161. unsigned int index = hashResult;
  162. while(storage[index]->next != NULL) //keep looking until find an empty cell, empty cell being storage[index]->next
  163. {
  164. index++;
  165. index = index%currentCap; //will loop back to 0 if index = currentCap
  166. }
  167. storage[(index+1)%currentCap] = &element; //put element into empty cell
  168. storage[index]->next = &element; //adjust previous cell's next pointer to correctly point at newly added element, maybe not needed
  169. element->next = storage[(index+2)%currentCap; //newly added element's next pointer points to next cell
  170. }
  171. }
  172. else //nothing there, add like normal
  173. {
  174. resize();
  175.  
  176. storage[hashResult] = &element;
  177. element.next = storage[(hashResult+1)%currentCap];
  178. if(storage[(hashResult-1)%currentCap] != NULL) //if previous node exists then change its next pointer accordingly
  179. storage[(hashResult-1)%currentCap]->next = &element;
  180. }
  181. }
  182.  
  183.  
  184. template <typename T>
  185. bool HashSet<T>::contains(const T& element) const
  186. {
  187. //lam
  188. unsigned int hashResult = hashFunction(element);
  189. if(storage[hashResult] != NULL) //something is there already
  190. {
  191. if(storage[hashResult]->item == element.item && storage[hashResult]->name == element.name) //the same one
  192. {
  193. return true;
  194. }
  195. else
  196. {
  197. unsigned int index = (hashResult+1)%currentCap;
  198. while(storage[index] != NULL)
  199. {
  200. if(storage[index]->item == element.item && storage[index]->name == element.name)
  201. return true;
  202. else
  203. {
  204. index++;
  205. index = index%currentCap;
  206. }
  207. }
  208. return false;
  209. }
  210. }
  211. else
  212. {
  213. return false;
  214. }
  215. }
  216.  
  217. template <typename T>
  218. unsigned int HashSet<T>::size() const
  219. {
  220. unsigned int count = 0;
  221. int i = 0;
  222. while(i < currentCap)
  223. {
  224. if(storage[i] != NULL) count++;
  225. i++;
  226. }
  227. return count;
  228. }
  229.  
  230. //lam
  231. template <typename T>
  232. void HashSet<T>::resize()
  233. {
  234. currentCap = currentCap*2;
  235. elementLink** newStorage;
  236. newStorage = new elementLink*[currentCap];
  237.  
  238. int i = 0;
  239. while(i < currentCap/2)
  240. {
  241. newStorage[i] = storage[i];
  242. i++;
  243. }
  244. delete[] storage;
  245. storage = newStorage;
  246. }
  247.  
  248. #endif // HASHSET_HPP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement