Advertisement
Guest User

Untitled

a guest
Mar 2nd, 2015
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.04 KB | None | 0 0
  1. #ifndef HASH_MAP_HPP_
  2. #define HASH_MAP_HPP_
  3.  
  4. #include <string>
  5. #include <iostream>
  6. #include <sstream>
  7. #include <initializer_list>
  8. #include "ics_exceptions.hpp"
  9. #include "iterator.hpp"
  10. #include "pair.hpp"
  11. #include "map.hpp"
  12. #include "array_queue.hpp" //For traversal
  13.  
  14.  
  15. namespace ics {
  16.  
  17. template<class KEY,class T> class HashMap : public Map<KEY,T> {
  18. public:
  19. typedef ics::pair<KEY,T> Entry;
  20. HashMap() = delete;
  21. HashMap(int (*ahash)(const KEY& k), double the_load_factor = 1.0);
  22. HashMap(int initial_bins, int (*ahash)(const KEY& k), double the_load_factor = 1.0);
  23. HashMap(const HashMap<KEY,T>& to_copy);
  24. HashMap(std::initializer_list<Entry> il, int (*ahash)(const KEY& k), double the_load_factor = 1.0);
  25. HashMap(ics::Iterator<Entry>& start, const ics::Iterator<Entry>& stop, int (*ahash)(const KEY& k), double the_load_factor = 1.0);
  26. virtual ~HashMap();
  27.  
  28. virtual bool empty () const;
  29. virtual int size () const;
  30. virtual bool has_key (const KEY& key) const;
  31. virtual bool has_value (const T& value) const;
  32. virtual std::string str () const;
  33.  
  34. virtual T put (const KEY& key, const T& value);
  35. virtual T erase (const KEY& key);
  36. virtual void clear ();
  37.  
  38. virtual int put (ics::Iterator<Entry>& start, const ics::Iterator<Entry>& stop);
  39.  
  40. virtual T& operator [] (const KEY&);
  41. virtual const T& operator [] (const KEY&) const;
  42. virtual HashMap<KEY,T>& operator = (const HashMap<KEY,T>& rhs);
  43. virtual bool operator == (const Map<KEY,T>& rhs) const;
  44. virtual bool operator != (const Map<KEY,T>& rhs) const;
  45.  
  46. template<class KEY2,class T2>
  47. friend std::ostream& operator << (std::ostream& outs, const HashMap<KEY2,T2>& m);
  48.  
  49. virtual ics::Iterator<Entry>& ibegin () const;
  50. virtual ics::Iterator<Entry>& iend () const;
  51.  
  52. private:
  53. class LN;
  54.  
  55. public:
  56. class Iterator : public ics::Iterator<Entry> {
  57. public:
  58. //KLUDGE should be callable only in begin/end
  59. Iterator(HashMap<KEY,T>* iterate_over, bool begin);
  60. Iterator(const Iterator& i);
  61. virtual ~Iterator();
  62. virtual Entry erase();
  63. virtual std::string str () const;
  64. virtual const ics::Iterator<Entry>& operator ++ ();
  65. virtual const ics::Iterator<Entry>& operator ++ (int);
  66. virtual bool operator == (const ics::Iterator<Entry>& rhs) const;
  67. virtual bool operator != (const ics::Iterator<Entry>& rhs) const;
  68. virtual Entry& operator * () const;
  69. virtual Entry* operator -> () const;
  70. private:
  71. ics::pair<int,LN*> current; //Bin Index/Cursor; stop: LN* == nullptr
  72. HashMap<KEY,T>* ref_map;
  73. int expected_mod_count;
  74. bool can_erase = true;
  75. void advance_cursors();
  76. };
  77.  
  78. virtual Iterator begin () const;
  79. virtual Iterator end () const;
  80. //KLUDGE: define
  81. //virtual ics::Iterator<KEY>& begin_key () const;
  82. //virtual ics::Iterator<KEY>& end_key () const;
  83. //virtual ics::Iterator<T>& begin_value () const;
  84. //virtual ics::Iterator<T>& end_value () const;
  85.  
  86. private:
  87. class LN {
  88. public:
  89. LN () : next(nullptr){}
  90. LN (const LN& ln) : value(ln.value), next(ln.next){}
  91. LN (Entry v, LN* n = nullptr) : value(v), next(n){}
  92.  
  93. Entry value;
  94. LN* next;
  95. };
  96.  
  97. LN** map = nullptr;
  98. int (*hash)(const KEY& k);
  99. double load_factor;//used/bins <= load_factor
  100. int bins = 1; //# bins available in the array
  101. int used = 0; //# of key->value pairs in the hash table
  102. int mod_count = 0; //For sensing concurrent modification
  103. int hash_compress (const KEY& key) const;
  104. void ensure_load_factor(int new_used);
  105. LN* find_key (int bin, const KEY& key) const;
  106. bool has_key(LN* l) const; //added to see if theres key
  107. bool find_value (const T& value) const;
  108. LN* copy_list(LN* l) const;
  109. LN** copy_hash_table(LN** ht, int bins) const;
  110. void delete_hash_table(LN**& ht, int bins);
  111. };
  112.  
  113.  
  114.  
  115.  
  116.  
  117. template<class KEY,class T>
  118. HashMap<KEY,T>::HashMap(int (*ahash)(const KEY& k), double the_load_factor) : hash(ahash), load_factor(the_load_factor) {
  119. map = new LN*[bins];
  120. map[0] = new LN();
  121. }
  122.  
  123. template<class KEY,class T>
  124. HashMap<KEY,T>::HashMap(int initial_bins, int (*ahash)(const KEY& k), double the_load_factor) : bins(initial_bins), hash(ahash), load_factor(the_load_factor) {
  125. //write code here
  126. }
  127.  
  128. template<class KEY,class T>
  129. HashMap<KEY,T>::HashMap(const HashMap<KEY,T>& to_copy) : hash(to_copy.hash), load_factor(to_copy.load_factor), bins(to_copy.bins), used(to_copy.used) {
  130. //write code here
  131. }
  132.  
  133. template<class KEY,class T>
  134. HashMap<KEY,T>::HashMap(ics::Iterator<Entry>& start, const ics::Iterator<Entry>& stop, int (*ahash)(const KEY& k), double the_load_factor) : hash(ahash), load_factor(the_load_factor) {
  135. //write code here
  136. }
  137.  
  138. template<class KEY,class T>
  139. HashMap<KEY,T>::HashMap(std::initializer_list<Entry> il,int (*ahash)(const KEY& k), double the_load_factor) : hash(ahash), load_factor(the_load_factor) {
  140. //write code here
  141. }
  142.  
  143. template<class KEY,class T>
  144. HashMap<KEY,T>::~HashMap() {
  145. delete[] map;
  146. }
  147.  
  148.  
  149. template<class KEY,class T>
  150. inline bool HashMap<KEY,T>::empty() const {
  151. return used == 0;
  152. }
  153.  
  154. template<class KEY,class T>
  155. int HashMap<KEY,T>::size() const {
  156. return used;
  157. }
  158.  
  159. template<class KEY,class T>
  160. bool HashMap<KEY,T>::has_key (const KEY& key) const {
  161. return find_key(hash_compress(key),key) != nullptr;
  162. }
  163.  
  164. template<class KEY,class T>
  165. bool HashMap<KEY,T>::has_value (const T& value) const {
  166. return find_value(value);
  167. }
  168.  
  169. template<class KEY,class T>
  170. std::string HashMap<KEY,T>::str() const {
  171. std::ostringstream answer;
  172. for ( int i = 0 ; i < bins ; ++i ) {
  173. answer << "bin[" << i << "]: ";
  174. for ( LN* temp = map[i] ; temp->next != nullptr ; temp=temp->next ) {
  175. answer << "pair[" << temp->value.first << "," << temp->value.second << "] -> ";
  176. }
  177. answer << "#" << std::endl;
  178. }
  179. return answer.str();
  180. }
  181.  
  182. template<class KEY,class T>
  183. T HashMap<KEY,T>::put(const KEY& key, const T& value) {
  184. LN* temp = new LN();
  185. if (has_key(key)) {
  186. int index = hash_compress(key);
  187. temp = find_key(index,key);
  188. temp->value.second = value;
  189. } else {
  190. ensure_load_factor(used+1);
  191. int index = hash_compress(key);
  192. temp->value.first = key;
  193. temp->value.second = value;
  194. temp->next = map[index];
  195. map[index] = temp;
  196. ++used;
  197. }
  198. ++mod_count;
  199. return temp->value.second;
  200. }
  201.  
  202. template<class KEY,class T>
  203. T HashMap<KEY,T>::erase(const KEY& key) {
  204. //write code here
  205. }
  206.  
  207. template<class KEY,class T>
  208. void HashMap<KEY,T>::clear() {
  209. used = 0;
  210. delete_hash_table(map,bins);
  211. ++mod_count;
  212. bins = 1;
  213. }
  214.  
  215. template<class KEY,class T>
  216. int HashMap<KEY,T>::put (ics::Iterator<Entry>& start, const ics::Iterator<Entry>& stop) {
  217. int count = 0;
  218. // for (; start != stop; ++start) {
  219. // ++count;
  220. // put(start->first,start->second);
  221. // }
  222. return count;
  223. }
  224.  
  225. template<class KEY,class T>
  226. T& HashMap<KEY,T>::operator [] (const KEY& key) {
  227. //write code here
  228. }
  229.  
  230. template<class KEY,class T>
  231. const T& HashMap<KEY,T>::operator [] (const KEY& key) const {
  232. //write code here
  233. }
  234.  
  235. template<class KEY,class T>
  236. bool HashMap<KEY,T>::operator == (const Map<KEY,T>& rhs) const {
  237. // //write code here
  238. // if (this == &rhs)
  239. // return true;
  240. // if (used != rhs.size())
  241. // return false;
  242. //// for (int i=0; i<used; ++i)
  243. //// // Uses ! and ==, so != on T need not be defined
  244. //// if (!rhs.has_key(map[i].first) || !(map[i].second == rhs[map[i].first]))
  245. //// return false;
  246. //
  247. // return true;
  248. }
  249.  
  250. template<class KEY,class T>
  251. HashMap<KEY,T>& HashMap<KEY,T>::operator = (const HashMap<KEY,T>& rhs) {
  252. //write code here
  253. }
  254.  
  255. template<class KEY,class T>
  256. bool HashMap<KEY,T>::operator != (const Map<KEY,T>& rhs) const {
  257. //write code here
  258. // return !(*this == rhs);
  259. }
  260.  
  261.  
  262. template<class KEY,class T>
  263. std::ostream& operator << (std::ostream& outs, const HashMap<KEY,T>& m) {
  264. outs << "map[";
  265.  
  266. if (!m.empty()) {
  267. for ( int i = 0 ; i < m.bins ; ++i ) {
  268. for ( auto temp = m.map[i] ; temp->next != nullptr ; temp = temp->next ) {
  269. outs << temp->value.first << "->" << temp->value.second << ",";
  270. }
  271. }
  272. }
  273.  
  274. outs << "]";
  275. return outs;
  276. }
  277.  
  278. //KLUDGE: memory-leak
  279. template<class KEY,class T>
  280. auto HashMap<KEY,T>::ibegin () const -> ics::Iterator<Entry>& {
  281. return *(new Iterator(const_cast<HashMap<KEY,T>*>(this),true));
  282. }
  283.  
  284. //KLUDGE: memory-leak
  285. template<class KEY,class T>
  286. auto HashMap<KEY,T>::iend () const -> ics::Iterator<Entry>& {
  287. return *(new Iterator(const_cast<HashMap<KEY,T>*>(this),false));
  288. }
  289.  
  290. template<class KEY,class T>
  291. auto HashMap<KEY,T>::begin () const -> HashMap<KEY,T>::Iterator {
  292. return Iterator(const_cast<HashMap<KEY,T>*>(this),true);
  293. }
  294.  
  295. template<class KEY,class T>
  296. auto HashMap<KEY,T>::end () const -> HashMap<KEY,T>::Iterator {
  297. return Iterator(const_cast<HashMap<KEY,T>*>(this),false);
  298. }
  299.  
  300. template<class KEY,class T>
  301. int HashMap<KEY,T>::hash_compress (const KEY& key) const {
  302. int w = abs(hash(key))%bins;
  303. return w;
  304. }
  305.  
  306. template<class KEY,class T>
  307. void HashMap<KEY,T>::ensure_load_factor(int new_used) {
  308. if (new_used/bins >= load_factor) {
  309. int new_bins = bins*2;
  310. LN** new_map = new LN*[new_bins];
  311. for ( int i = 0 ; i < new_bins ; ++i ) {
  312. new_map[i] = new LN();
  313. }
  314. for ( int i = 0 ; i < bins ; ++i ) {
  315.  
  316. }
  317. }
  318. }
  319.  
  320. template<class KEY,class T>
  321. typename HashMap<KEY,T>::LN* HashMap<KEY,T>::find_key (int bin, const KEY& key) const {
  322. if (used == 0)
  323. return nullptr;
  324. else {
  325. for ( LN* temp = map[bin] ; temp != nullptr ; temp = temp->next ) {
  326. if ( temp->value.first == key )
  327. return temp;
  328. }
  329. return nullptr;
  330. }
  331. }
  332.  
  333. template<class KEY,class T>
  334. bool HashMap<KEY,T>::has_key (LN* l) const {
  335. if(l == nullptr){
  336. return false;
  337. } else{
  338. return true;
  339. }
  340. }
  341.  
  342. template<class KEY,class T>
  343. bool HashMap<KEY,T>::find_value (const T& value) const {
  344. if (used == 0)
  345. return false;
  346. else {
  347. for ( int i = 0 ; i < bins ; ++i ) {
  348. for ( HashMap<KEY,T>::LN* temp = map[i] ; temp->next != nullptr ; temp = temp->next ) {
  349. if ( temp->value.second == value )
  350. return true;
  351. }
  352. }
  353. return false;
  354. }
  355. }
  356.  
  357. template<class KEY,class T>
  358. typename HashMap<KEY,T>::LN* HashMap<KEY,T>::copy_list (LN* l) const {
  359. // LN* to_copy = new LN();
  360. // std::cout << "start copylist" << std::endl;
  361. // if(l->next == nullptr){
  362. // std::cout << "hi" << std::endl;
  363. // return to_copy;
  364. // }
  365. //// for(LN* temp = l; temp != nullptr; temp = temp->next){
  366. //// to_copy->value.first = temp->value.first;
  367. //// to_copy->value.second = temp->value.second;
  368. //// to_copy->next = temp->next;
  369. //// std::cout << "helllo" << std::endl;
  370. //// }
  371. // std::cout << "end copylist" << std::endl;
  372. // return to_copy;
  373. }
  374.  
  375. template<class KEY,class T>
  376. typename HashMap<KEY,T>::LN** HashMap<KEY,T>::copy_hash_table (LN** ht, int bins) const {
  377. LN** to_copy = new LN*[bins];
  378. for(int i = 0; i < bins; ++i){
  379. to_copy[i] = copy_list(map[i]);
  380. }
  381. return to_copy;
  382. }
  383.  
  384. template<class KEY,class T>
  385. void HashMap<KEY,T>::delete_hash_table (LN**& ht, int bins) {
  386. for(int i = 0; i < bins; ++i){
  387. delete[] ht[i];
  388. }
  389. }
  390.  
  391.  
  392. template<class KEY,class T>
  393. void HashMap<KEY,T>::Iterator::advance_cursors(){
  394. //write code here
  395. }
  396.  
  397. template<class KEY,class T>
  398. HashMap<KEY,T>::Iterator::Iterator(HashMap<KEY,T>* iterate_over, bool begin) : ref_map(iterate_over) {
  399. //write code here
  400. }
  401.  
  402. template<class KEY,class T>
  403. HashMap<KEY,T>::Iterator::Iterator(const Iterator& i) :
  404. current(i.current), ref_map(i.ref_map), expected_mod_count(i.expected_mod_count), can_erase(i.can_erase) {}
  405.  
  406. template<class KEY,class T>
  407. HashMap<KEY,T>::Iterator::~Iterator()
  408. {}
  409.  
  410. template<class KEY,class T>
  411. auto HashMap<KEY,T>::Iterator::erase() -> Entry {
  412. if (expected_mod_count != ref_map->mod_count)
  413. throw ConcurrentModificationError("HashMap::Iterator::erase");
  414. if (!can_erase)
  415. throw CannotEraseError("HashMap::Iterator::erase Iterator cursor already erased");
  416. if (current.second == nullptr)
  417. throw CannotEraseError("HashMap::Iterator::erase Iterator cursor beyond data structure");
  418.  
  419. //write code here
  420. }
  421.  
  422. template<class KEY,class T>
  423. std::string HashMap<KEY,T>::Iterator::str() const {
  424. std::ostringstream answer;
  425. answer << ref_map->str() << "(current=" << current.first << "/" << current.second << ",expected_mod_count=" << expected_mod_count << ",can_erase=" << can_erase << ")";
  426. return answer.str();
  427. }
  428.  
  429. //KLUDGE: cannot use Entry
  430. template<class KEY,class T>
  431. auto HashMap<KEY,T>::Iterator::operator ++ () -> const ics::Iterator<ics::pair<KEY,T>>& {
  432. if (expected_mod_count != ref_map->mod_count)
  433. throw ConcurrentModificationError("HashMap::Iterator::operator ++");
  434.  
  435. //write code here
  436. }
  437.  
  438. //KLUDGE: creates garbage! (can return local value!)
  439. template<class KEY,class T>
  440. auto HashMap<KEY,T>::Iterator::operator ++ (int) -> const ics::Iterator<ics::pair<KEY,T>>&{
  441. if (expected_mod_count != ref_map->mod_count)
  442. throw ConcurrentModificationError("HashMap::Iterator::operator ++(int)");
  443.  
  444. //write code here
  445. }
  446.  
  447. template<class KEY,class T>
  448. bool HashMap<KEY,T>::Iterator::operator == (const ics::Iterator<Entry>& rhs) const {
  449. const Iterator* rhsASI = dynamic_cast<const Iterator*>(&rhs);
  450. if (rhsASI == 0)
  451. throw IteratorTypeError("HashMap::Iterator::operator ==");
  452. if (expected_mod_count != ref_map->mod_count)
  453. throw ConcurrentModificationError("HashMap::Iterator::operator ==");
  454. if (ref_map != rhsASI->ref_map)
  455. throw ComparingDifferentIteratorsError("HashMap::Iterator::operator ==");
  456.  
  457. //write code here
  458. }
  459.  
  460.  
  461. template<class KEY,class T>
  462. bool HashMap<KEY,T>::Iterator::operator != (const ics::Iterator<Entry>& rhs) const {
  463. const Iterator* rhsASI = dynamic_cast<const Iterator*>(&rhs);
  464. if (rhsASI == 0)
  465. throw IteratorTypeError("HashMap::Iterator::operator !=");
  466. if (expected_mod_count != ref_map->mod_count)
  467. throw ConcurrentModificationError("HashMap::Iterator::operator !=");
  468. if (ref_map != rhsASI->ref_map)
  469. throw ComparingDifferentIteratorsError("HashMap::Iterator::operator !=");
  470.  
  471. //write code here
  472. }
  473.  
  474. template<class KEY,class T>
  475. ics::pair<KEY,T>& HashMap<KEY,T>::Iterator::operator *() const {
  476. if (expected_mod_count !=
  477. ref_map->mod_count)
  478. throw ConcurrentModificationError("HashMap::Iterator::operator *");
  479. if (!can_erase || current.second == nullptr)
  480. throw IteratorPositionIllegal("HashMap::Iterator::operator * Iterator illegal: exhausted");
  481.  
  482. //write code here
  483. }
  484.  
  485. template<class KEY,class T>
  486. ics::pair<KEY,T>* HashMap<KEY,T>::Iterator::operator ->() const {
  487. if (expected_mod_count !=
  488. ref_map->mod_count)
  489. throw ConcurrentModificationError("HashMap::Iterator::operator *");
  490. if (!can_erase || current.second == nullptr)
  491. throw IteratorPositionIllegal("HashMap::Iterator::operator -> Iterator illegal: exhausted");
  492.  
  493. //write code here
  494. }
  495.  
  496. }
  497.  
  498. #endif /* HASH_MAP_HPP_ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement