Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
Multiset.H
1 /*
2  Aleph implementation of multiset C++ standard container
3 */
4 
5 # ifndef AH_MULTISET_H
6 # define AH_MULTISET_H
7 
8 # include <memory>
9 # include <ah_stdc++_utils.H>
10 # include <tpl_dnode.H>
11 # include <tpl_treapRk.H>
12 # include <tpl_nodePool.H>
13 
14 namespace Aleph
15 {
16 
38  template <class T,
39  class Compare = Aleph::less<T>,
40  template <class, class> class Tree = Treap_Rk
41  >
42 class multiset
43 {
44  struct Node_Data
45  {
46  mutable T key;
47  mutable size_t num_reps;
48 
49  Node_Data() : num_reps(0) { /* empty */ }
50 
51  Node_Data(const T & k) : key(k), num_reps(1) { /* empty */ }
52  };
53 
54  struct Cmp_Data
55  {
56  bool operator () (const Node_Data & op1, const Node_Data & op2) const
57  {
58  return Compare () (op1.key, op2.key);
59  }
60  };
61 
62 public:
63 
65  typedef T value_type;
66 
68  typedef typename multiset::value_type & reference;
69 
71  typedef const typename multiset::value_type & const_reference;
72 
74  typedef size_t size_type;
75 
77  typedef T key_type;
78 
79 private:
80 
81  typedef Tree<Node_Data, Cmp_Data> Tree_Type;
82 
83  typedef typename Tree_Type::Node Node;
84 
85  typedef typename Tree_Type::Iterator Tree_Iterator;
86 
87  mutable Tree_Type tree;
88 
89  mutable size_t num_elem;
90 
91  Node_Pool<Node> pool;
92 
93  static T & get_key(Node * p) { return KEY(p).key; }
94 
95  static size_t & get_num_reps(Node * p) { return KEY(p).num_reps; }
96 
97 public:
98 
103  class iterator
104  {
105  private:
106 
107  friend class multiset<T, Compare, Tree>;
108 
109  typedef typename Tree_Type::Iterator Iterator;
110 
111  mutable multiset * multiset_ptr;
112 
113  mutable Iterator tree_it;
114 
115  mutable int pos_in_node;
116 
117  bool overflow;
118  bool underflow;
119 
120  iterator (multiset * mset_ptr, Node * curr_tree_node, int pos = 0)
121  : multiset_ptr(mset_ptr), tree_it(mset_ptr->tree, curr_tree_node),
122  pos_in_node(pos), overflow (false), underflow (false)
123  {
124  // empty
125  }
126 
127  void default_init ()
128  {
129  if (tree_it.has_curr ())
130  {
131  underflow = overflow = false;
132  pos_in_node = 0;
133  }
134  else
135  underflow = overflow = true;
136  }
137 
138  iterator(const multiset & ms)
139  : multiset_ptr(const_cast<multiset*>(&ms)), tree_it(ms.tree)
140  {
141  default_init();
142  }
143 
144  Node * get_curr_node() { return tree_it.get_curr(); }
145 
146  bool has_curr() const
147  {
148  return tree_it.has_curr();
149  }
150 
151  Node_Data & get_data() { return KEY(get_curr_node()); }
152 
153  T & get_key() { return multiset::get_key(get_curr_node()); }
154 
155  size_t & get_num_reps() { return multiset::get_num_reps(get_curr_node()); }
156 
157  public:
158 
161 
165 
167  typedef typename multiset<T>::value_type * pointer;
168 
171 
173  typedef const typename multiset<T>::reference const_reference;
174 
175  iterator(multiset * mset_ptr)
176  : multiset_ptr(mset_ptr), tree_it(multiset_ptr->tree)
177  {
178  default_init();
179  }
180 
181  iterator(const iterator & it)
182  : multiset_ptr(it.multiset_ptr), tree_it(it.tree_it),
183  pos_in_node(it.pos_in_node),
184  overflow(it.overflow), underflow(it.underflow)
185  {
186  // empty
187  }
188 
191  {
192  underflow = overflow = true;
193  pos_in_node = -1;
194  }
195 
197  const T & operator * ()
198  {
199  return get_key();
200  }
201 
203  const T * operator -> ()
204  {
205  return & get_key();
206  }
207 
208  private:
209 
210  void goto_begin ()
211  {
212  tree_it.reset_first ();
213  if (tree_it.has_curr ())
214  {
215  underflow = false;
216  pos_in_node = 0;
217  }
218  else
219  {
220  underflow = true;
221  pos_in_node = -1;
222  }
223  }
224 
225  void goto_last ()
226  {
227  tree_it.reset_last ();
228  if (tree_it.has_curr ())
229  {
230  overflow = false;
231  pos_in_node = get_num_reps() - 1;
232  }
233  else
234  {
235  overflow = true;
236  pos_in_node = -1;
237  }
238  }
239 
240  void goto_end ()
241  {
242  tree_it.reset_last();
243  if (tree_it.has_curr())
244  { // el árbol no está vacío
245  tree_it.next (); // coloca tree_it fuera de rango
246  underflow = false;
247  }
248  else
249  underflow = true;
250 
251  pos_in_node = -1;
252  overflow = true;
253  }
254 
255  iterator compute_end() const
256  {
257  iterator it(*this);
258  it.goto_end();
259  return it;
260  }
261 
262  bool is_at_end() const
263  {
264  return not tree_it.has_curr();
265  }
266 
267  iterator compute_begin() const
268  {
269  iterator it(*this);
270  return it;
271  }
272 
273  void forward ()
274  {
275  if (underflow)
276  {
277  goto_begin ();
278  return;
279  }
280 
281  if (++pos_in_node == get_num_reps())
282  {
283  tree_it.next ();
284 
285  if (tree_it.has_curr ())
286  pos_in_node = 0;
287  else
288  {
289  overflow = true;
290  pos_in_node = -1;
291  I(*this == compute_end());
292  }
293  }
294  }
295 
296  void backward ()
297  {
298  if (overflow)
299  {
300  goto_last ();
301  return;
302  }
303 
304  if (pos_in_node-- == 0)
305  {
306  tree_it.prev ();
307 
308  if (tree_it.has_curr ())
309  pos_in_node = get_num_reps();
310  else
311  underflow = true;
312  }
313  }
314 
315  void del()
316  {
317  Node * tree_node = get_curr_node();
318  size_t & num_reps = multiset::get_num_reps(tree_node);
319 
320  --num_reps;
321 
322  --multiset_ptr->num_elem;
323 
324  if (num_reps == 0)
325  {
326  tree_it.del();
327  multiset_ptr->pool.deallocate(tree_node);
328 
329  if (tree_it.has_curr ())
330  pos_in_node = 0;
331  else
332  {
333  overflow = true;
334  pos_in_node = -1;
335  }
336  }
337  }
338 
339  public:
340 
344  {
345  forward ();
346  return *this;
347  }
348 
351  {
352  iterator ret_val = *this;
353  forward ();
354  return ret_val;
355  }
356 
360  {
361  backward ();
362  return *this;
363  }
364 
366  T & operator -- (int)
367  {
368  iterator ret_val = *this;
369  backward ();
370  return ret_val;
371  }
372 
376  {
377  for (int i = 0; i < n; ++i)
378  forward ();
379 
380  return *this;
381  }
382 
386  {
387  for (int i = 0; i < n; ++i)
388  backward ();
389 
390  return *this;
391  }
392 
394  bool operator == (const iterator & it) const
395  {
396  if (this->has_curr() and it.has_curr())
397  return pos_in_node == it.pos_in_node;
398 
399  if (this->is_at_end() and it.is_at_end())
400  {
401  I(this->overflow and it.overflow);
402  return true;
403  }
404 
405  return false;
406  }
407 
409  bool operator != (const iterator & itor) const
410  {
411  return not (*this == itor);
412  }
413 
414  bool verify (const multiset & _multiset) const
415  {
416  return tree_it.verify ( (Tree_Type*)& (_multiset.tree));
417  }
418 
419  bool verify (const iterator & it) const
420  {
421  return tree_it.verify (it.tree_it);
422  }
423  }; // class iterator;
424 
427 
430 
433 
435  multiset () : num_elem (0), pool(100) { /* empty */ }
436 
437 private:
438 
439  void copy (const multiset & c)
440  {
441  tree.getRoot () = copyRec(c.tree.getRoot());
442  }
443 
444 public:
445 
447  multiset (const multiset & c) : num_elem (c.num_elem), pool(100)
448  {
449  copy (c);
450  }
451 
467  template <typename Itor>
468  multiset (Itor beg, const Itor & end) : multiset()
469  {
470  while (beg != end)
471  insert (*beg++);
472  }
473 
477  {
478  destroyRec(tree.getRoot());
479  }
480 
483  {
484  if (this == &c)
485  return *this;
486 
487  destroyRec(tree.getRoot());
488 
489  copy(c);
490 
491  num_elem = c.num_elem;
492 
493  return *this;
494  }
495 
497  size_type size () const { return num_elem; }
498 
500  bool empty () const
501  {
502  return COUNT(tree.getRoot ()) == 0;
503  }
504 
507  bool operator == (const multiset & c) const
508  {
509  if (this == &c)
510  return true;
511 
512  if (size () != c.size ())
513  return false;
514 
515  Tree_Iterator itor1 (tree), itor2 (c.tree);
516 
517  while (itor1.has_curr() and itor2.has_curr())
518  {
519  Node * p1 = itor1.get_curr();
520  Node * p2 = itor2.get_curr();
521 
522  if (no_equals <Node_Data, Cmp_Data> (KEY(p1), KEY(p2)))
523  return false;
524  else if (get_num_reps(p1) != get_num_reps(p2))
525  return false;
526 
527  itor1.next ();
528  itor2.next ();
529  }
530 
531  return not itor1.has_curr() and not itor2.has_curr();
532  }
533 
536  bool operator != (const multiset & c) const
537  {
538  return not (*this == c);
539  }
540 
543  bool operator < (const multiset & c) const
544  {
545  if (this == &c)
546  return false;
547 
548  iterator itor1 (*this), itor2 (c);
549 
550  while (itor1.has_curr() and itor2.has_curr())
551  {
552  if (Cmp_Data () (itor1.get_data(), itor2.get_data()))
553  return true;
554  else if (Cmp_Data () (itor2.get_data(), itor1.get_data()))
555  return false; // no son iguales
556 
557  itor1.forward();
558  itor2.forward();
559  }
560 
561  if (itor1.has_curr()) /* |*this| >= |c| */
562  return false;
563 
564  return itor2.has_curr();
565  }
566 
569  bool operator > (const multiset & c) const
570  {
571  return not (*this == c or *this < c);
572  }
573 
576  bool operator <= (const multiset & c) const
577  {
578  return not (*this > c );
579  }
580 
583  bool operator >= (const multiset & c) const
584  {
585  return not (*this < c);
586  }
587 
595  size_type count (const T & value) const
596  {
597  Node * p = tree.search (Node_Data(value));
598 
599  if (p == NULL)
600  return 0;
601 
602  return get_num_reps(p);
603  }
604 
622  iterator find (const T & value) const
623  {
624  Node * node = tree.search(Node_Data(value));
625 
626  if (node == NULL)
627  return end ();
628 
629  return iterator(const_cast<multiset*>(this), node);
630  }
631 
647  iterator lower_bound (const T & value) const
648  {
649  if (size () == 0)
650  throw std::underflow_error ("multiset is empty");
651 
652  Node * tree_node = tree.search(Node_Data(value));
653 
654  if (tree_node == NULL)
655  return end ();
656 
657  return iterator (this, tree_node);
658  }
659 
675  iterator upper_bound (const T & value) const
676  {
677  if (size () == 0)
678  throw std::underflow_error("multiset is empty");
679 
680  Node * tree_node = tree.search(Node_Data(value));
681 
682  if (tree_node == NULL)
683  return end ();
684 
685  iterator it (this, tree_node);
686  it.list_it.reset_last ();
687 
688  return it;
689  }
690 
693  void swap (multiset & c)
694  {
695  std::swap (tree.getRoot (), c.tree.getRoot ());
696  std::swap (num_elem, c.num_elem);
697  }
698 
701  iterator begin () const
702  {
703  return iterator (*this);
704  }
705 
708  iterator end () const
709  {
710  return iterator(*this).compute_end();
711  }
712 
722  iterator insert (const T & value)
723  {
724  Node * p = pool.allocate(Node_Data(value));
725  Node * ptr = tree.search_or_insert(p);
726 
727  if (ptr != p) // ya está value en el árbol
728  pool.deallocate(p);
729 
730  ++num_elem;
731 
732  return iterator(this, ptr, get_num_reps(ptr)++);
733  }
734 
760  iterator insert (iterator pos, const T & value)
761  {
762  Aleph::verify_container_and_iterator (this, pos);
763 
764  if (pos != pos.compute_end())
765  {
766  Node * p = pos.get_curr_node();
767 
768  if (are_equals <Node_Data, Cmp_Data> (KEY(p), Node_Data(value)))
769  {
770  get_num_reps(p)++;
771  pos.pos_in_node++;
772 
773  return pos;
774  }
775  }
776 
777  return insert(value);
778  }
779 
797  template <typename Itor>
798  void insert (Itor beg, const Itor & end)
799  {
800  Aleph::verify_iterators (beg, end);
801 
802  while (beg != end)
803  insert(*beg++);
804  }
805 
814  size_type erase (const T & value)
815  {
816  Node * tree_node = tree.remove(Node_Data(value));
817 
818  if (tree_node == NULL)
819  return 0;
820 
821  const size_t ret_val = get_num_reps(tree_node);
822 
823  pool.deallocate(tree_node);
824 
825  num_elem -= ret_val;
826 
827  return ret_val;
828  }
829 
843  void erase (iterator pos)
844  {
845  Aleph::verify_container_and_iterator (*this, pos);
846 
847  Node * tree_node = pos.get_curr_node();
848 
849  size_t & num_reps = get_num_reps(tree_node);
850 
851  --num_reps;
852  --num_elem;
853 
854  if (num_reps == 0)
855  {
856  tree.remove(Node_Data(KEY(tree_node)));
857  pool.deallocate(tree_node);
858  }
859  }
860 
861 private:
862 
863  /* Borra el rango secuencialmente */
864  iterator delete_range (iterator beg, const iterator & end)
865  {
866  while (beg != end)
867  beg.del();
868 
869  return beg;
870  }
871 
872 public:
873 
887  iterator erase (iterator beg, const iterator & end)
888  {
889  Aleph::verify_container_and_iterator (*this, beg);
890  Aleph::verify_iterators (beg, end);
891 
892  return delete_range(beg, end);
893  }
894 
896  void clear ()
897  {
898  destroyRec (static_cast<Node *> (tree.getRoot ()));
899  num_elem = 0;
900  }
901 };
902 
903 
904  template <typename T>
905 typename iterator_traits<typename multiset<T>::iterator>::difference_type
906 distance (typename multiset<T>::iterator it1,
907  typename multiset<T>::iterator it2)
908 {
909  typename iterator_traits<typename multiset<T>::iterator>::difference_type
910  counter = 0;
911 
912 
913  while (it1 != it2)
914  {
915  ++counter;
916  ++it1;
917  }
918 
919  return counter;
920 }
921 
922 } // end namespace Aleph
923 
924 # endif // AH_MULTISET_H
Definition: Multiset.H:103
multiset< T >::value_type * pointer
Tipo apuntador a elemento dentro del multi-conjunto.
Definition: Multiset.H:167
iterator find(const T &value) const
Definition: Multiset.H:622
Definition: tpl_treapRk.H:902
Definition: tpl_nodePool.H:19
size_type size() const
Retorna la cantidad de elementos que contiene el multi-conjunto.
Definition: Multiset.H:497
multiset::iterator const_iterator
Tipo iterador constante.
Definition: Multiset.H:426
size_type count(const T &value) const
Definition: Multiset.H:595
Definition: ahFunction.H:145
size_t size_type
Tipo numérico para los tamaños (natural).
Definition: Multiset.H:74
iterator begin() const
Definition: Multiset.H:701
iterator operator+=(size_type n)
Definition: Multiset.H:375
multiset()
Constructor vacío de un multi-conjunto.
Definition: Multiset.H:435
iterator insert(iterator pos, const T &value)
Definition: Multiset.H:760
multiset::value_type & reference
Tipo genérico de referencia a elemento del conjunto.
Definition: Multiset.H:68
void swap(multiset &c)
Definition: Multiset.H:693
#define COUNT(p)
Definition: tpl_binNodeXt.H:34
void erase(iterator pos)
Definition: Multiset.H:843
multiset(const multiset &c)
Instancia una copia del multi-conjunto c.
Definition: Multiset.H:447
multiset & operator=(const multiset &c)
Asigna todo el contenido de c a this.
Definition: Multiset.H:482
multiset< T >::value_type value_type
El tipo de dato que contiene el multi-conjunto.
Definition: Multiset.H:160
bool operator==(const multiset &c) const
Definition: Multiset.H:507
Definition: ahIterator.H:8
T key_type
El tipo dato de los elementos del conjunto.
Definition: Multiset.H:77
~multiset()
Definition: Multiset.H:476
const T & operator*()
Proporciona una referencia al elemento actual.
Definition: Multiset.H:197
const T * operator->()
"Dereferencia" un puntero al elemento actual.
Definition: Multiset.H:203
iterator upper_bound(const T &value) const
Definition: Multiset.H:675
bool operator!=(const multiset &c) const
Definition: Multiset.H:536
Definition: Multiset.H:42
iterator erase(iterator beg, const iterator &end)
Definition: Multiset.H:887
bool operator==(const iterator &it) const
Retorna true si los iteradores tienen el mismo estado.
Definition: Multiset.H:394
void insert(Itor beg, const Itor &end)
Definition: Multiset.H:798
void destroyRec(Node *&root)
Definition: tpl_binNodeUtils.H:798
bool operator>=(const multiset &c) const
Definition: Multiset.H:583
bool operator<(const multiset &c) const
Definition: Multiset.H:543
T value_type
El tipo dato de los elementos del conjunto.
Definition: Multiset.H:65
iterator end() const
Definition: Multiset.H:708
bool empty() const
Retorna true si el contenedor esta vacío.
Definition: Multiset.H:500
Node * copyRec(Node *src_root)
Definition: tpl_binNodeUtils.H:821
multiset::iterator const_reverse_iterator
Tipo iterador invertido constante.
Definition: Multiset.H:432
iterator operator++()
Definition: Multiset.H:343
void clear()
Borra todos los elementos del multi-conjunto.
Definition: Multiset.H:896
iterator lower_bound(const T &value) const
Definition: Multiset.H:647
iterator operator-=(size_type n)
Definition: Multiset.H:385
iterator insert(const T &value)
Definition: Multiset.H:722
bool operator>(const multiset &c) const
Definition: Multiset.H:569
multiset< T >::size_type difference_type
Definition: Multiset.H:164
#define KEY(p)
Definition: tpl_binNode.H:206
bool operator!=(const iterator &itor) const
Retorna true si los iteradores tienen estados distintos.
Definition: Multiset.H:409
multiset::iterator reverse_iterator
Tipo iterador invertido.
Definition: Multiset.H:429
bool operator<=(const multiset &c) const
Definition: Multiset.H:576
iterator()
Constructor vacío; no tiene validez si no se asocia un conjunto.
Definition: Multiset.H:190
multiset(Itor beg, const Itor &end)
Definition: Multiset.H:468
multiset< T >::reference reference
Tipo referencia a elemento dentro del multi-conjunto.
Definition: Multiset.H:170
const multiset::value_type & const_reference
Tipo genérico de referencia constante a elemento del conjunto.
Definition: Multiset.H:71
size_type erase(const T &value)
Definition: Multiset.H:814
const multiset< T >::reference const_reference
Tipo referencia a elemento dentro del multi-conjunto.
Definition: Multiset.H:173
iterator operator--()
Definition: Multiset.H:359

Leandro Rabindranath León