Advertisement
Guest User

Untitled

a guest
May 24th, 2015
356
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.76 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. }
  123.  
  124.  
  125. template <typename T>
  126. HashSet<T>& HashSet<T>::operator=(const HashSet& s)
  127. {
  128. if (this != &s)
  129. {
  130. hashFunction = s.hashFunction;
  131. }
  132.  
  133. return *this;
  134. }
  135.  
  136.  
  137. template <typename T>
  138. bool HashSet<T>::isImplemented() const
  139. {
  140. return false;
  141. }
  142.  
  143.  
  144. template <typename T>
  145. void HashSet<T>::add(const T& element)
  146. {
  147. //lam
  148. unsigned int hashResult = hashFunction(element);
  149. if(storage[hashResult] != NULL) //something is there already
  150. {
  151. if(contains(element)) //the same one
  152. {
  153. return; //nothing happen
  154. }
  155. else //not the same
  156. {
  157. resize();
  158.  
  159. unsigned int index = hashResult;
  160. while(storage[index]->next != NULL) //keep looking until find an empty cell, empty cell being storage[index]->next
  161. {
  162. index++;
  163. index = index%currentCap; //will loop back to 0 if index = currentCap
  164. }
  165. storage[(index+1)%currentCap] = &element; //put element into empty cell
  166. storage[index]->next = &element; //adjust previous cell's next pointer to correctly point at newly added element, maybe not needed
  167. element->next = storage[(index+2)%currentCap; //newly added element's next pointer points to next cell
  168. }
  169. }
  170. else //nothing there, add like normal
  171. {
  172. resize();
  173.  
  174. storage[hashResult] = &element;
  175. element.next = storage[(hashResult+1)%currentCap];
  176. if(storage[(hashResult-1)%currentCap] != NULL) //if previous node exists then change its next pointer accordingly
  177. storage[(hashResult-1)%currentCap]->next = &element;
  178. }
  179. }
  180.  
  181.  
  182. template <typename T>
  183. bool HashSet<T>::contains(const T& element) const
  184. {
  185. //lam
  186. unsigned int hashResult = hashFunction(element);
  187. if(storage[hashResult] != NULL) //something is there already
  188. {
  189. if(storage[hashResult]->item == element.item && storage[hashResult]->name == element.name) //the same one
  190. {
  191. return true;
  192. }
  193. else
  194. {
  195. unsigned int index = (hashResult+1)%currentCap;
  196. while(storage[index] != NULL)
  197. {
  198. if(storage[index]->item == element.item && storage[index]->name == element.name)
  199. return true;
  200. else
  201. {
  202. index++;
  203. index = index%currentCap;
  204. }
  205. }
  206. return false;
  207. }
  208. }
  209. else
  210. {
  211. return false;
  212. }
  213. }
  214.  
  215. template <typename T>
  216. unsigned int HashSet<T>::size() const
  217. {
  218. unsigned int count = 0;
  219. int i = 0;
  220. while(i < currentCap)
  221. {
  222. if(storage[i] != NULL) count++;
  223. i++;
  224. }
  225. return count;
  226. }
  227.  
  228. //lam
  229. template <typename T>
  230. void HashSet<T>::resize()
  231. {
  232. currentCap = currentCap*2;
  233. elementLink** newStorage;
  234. newStorage = new elementLink*[currentCap];
  235.  
  236. int i = 0;
  237. while(i < currentCap/2)
  238. {
  239. newStorage[i] = storage[i];
  240. i++;
  241. }
  242. delete[] storage;
  243. storage = newStorage;
  244. }
  245.  
  246. #endif // HASHSET_HPP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement