215 idx = next; |
245 idx = next; |
216 } |
246 } |
217 return k; |
247 return k; |
218 } |
248 } |
219 |
249 |
220 void unlaceClass(int k) { |
250 int classIndex(int idx) const { |
221 if (items[k].prevClass != -1) { |
251 return ~(items[repIndex(idx)].parent); |
222 items[items[k].prevClass].nextClass = items[k].nextClass; |
252 } |
|
253 |
|
254 void singletonItem(int idx) { |
|
255 items[idx].next = idx; |
|
256 items[idx].prev = idx; |
|
257 } |
|
258 |
|
259 void laceItem(int idx, int rdx) { |
|
260 items[idx].prev = rdx; |
|
261 items[idx].next = items[rdx].next; |
|
262 items[items[rdx].next].prev = idx; |
|
263 items[rdx].next = idx; |
|
264 } |
|
265 |
|
266 void unlaceItem(int idx) { |
|
267 items[items[idx].prev].next = items[idx].next; |
|
268 items[items[idx].next].prev = items[idx].prev; |
|
269 |
|
270 items[idx].next = firstFreeItem; |
|
271 firstFreeItem = idx; |
|
272 } |
|
273 |
|
274 void spliceItems(int ak, int bk) { |
|
275 items[items[ak].prev].next = bk; |
|
276 items[items[bk].prev].next = ak; |
|
277 int tmp = items[ak].prev; |
|
278 items[ak].prev = items[bk].prev; |
|
279 items[bk].prev = tmp; |
|
280 |
|
281 } |
|
282 |
|
283 void laceClass(int cls) { |
|
284 if (firstClass != -1) { |
|
285 classes[firstClass].prev = cls; |
|
286 } |
|
287 classes[cls].next = firstClass; |
|
288 classes[cls].prev = -1; |
|
289 firstClass = cls; |
|
290 } |
|
291 |
|
292 void unlaceClass(int cls) { |
|
293 if (classes[cls].prev != -1) { |
|
294 classes[classes[cls].prev].next = classes[cls].next; |
223 } else { |
295 } else { |
224 firstClass = items[k].nextClass; |
296 firstClass = classes[cls].next; |
225 } |
297 } |
226 if (items[k].nextClass != -1) { |
298 if (classes[cls].next != -1) { |
227 items[items[k].nextClass].prevClass = items[k].prevClass; |
299 classes[classes[cls].next].prev = classes[cls].prev; |
228 } |
300 } |
|
301 |
|
302 classes[cls].next = firstFreeClass; |
|
303 firstFreeClass = cls; |
229 } |
304 } |
230 |
305 |
231 void spliceItems(int ak, int bk) { |
|
232 items[items[ak].prevItem].nextItem = bk; |
|
233 items[items[bk].prevItem].nextItem = ak; |
|
234 int tmp = items[ak].prevItem; |
|
235 items[ak].prevItem = items[bk].prevItem; |
|
236 items[bk].prevItem = tmp; |
|
237 |
|
238 } |
|
239 |
|
240 public: |
306 public: |
241 |
307 |
242 UnionFindEnum(ItemIntMap& _index) |
308 UnionFindEnum(ItemIntMap& _index) |
243 : items(), index(_index), firstClass(-1) {} |
309 : index(_index), items(), firstFreeItem(-1), |
|
310 firstClass(-1), firstFreeClass(-1) {} |
244 |
311 |
245 /// \brief Inserts the given element into a new component. |
312 /// \brief Inserts the given element into a new component. |
246 /// |
313 /// |
247 /// This method creates a new component consisting only of the |
314 /// This method creates a new component consisting only of the |
248 /// given element. |
315 /// given element. |
249 /// |
316 /// |
250 void insert(const Item& item) { |
317 int insert(const Item& item) { |
251 ItemT t; |
318 int idx = newItem(); |
252 |
319 |
253 int idx = items.size(); |
|
254 index.set(item, idx); |
320 index.set(item, idx); |
255 |
321 |
256 t.nextItem = idx; |
322 singletonItem(idx); |
257 t.prevItem = idx; |
323 items[idx].item = item; |
258 t.item = item; |
324 |
259 t.parent = -1; |
325 int cdx = newClass(); |
260 |
326 |
261 t.nextClass = firstClass; |
327 items[idx].parent = ~cdx; |
262 if (firstClass != -1) { |
328 |
263 items[firstClass].prevClass = idx; |
329 laceClass(cdx); |
264 } |
330 classes[cdx].size = 1; |
265 t.prevClass = -1; |
331 classes[cdx].firstItem = idx; |
266 firstClass = idx; |
332 |
267 |
333 firstClass = cdx; |
268 items.push_back(t); |
334 |
|
335 return cdx; |
269 } |
336 } |
270 |
337 |
271 /// \brief Inserts the given element into the component of the others. |
338 /// \brief Inserts the given element into the component of the others. |
272 /// |
339 /// |
273 /// This methods inserts the element \e a into the component of the |
340 /// This methods inserts the element \e a into the component of the |
274 /// element \e comp. |
341 /// element \e comp. |
275 void insert(const Item& item, const Item& comp) { |
342 void insert(const Item& item, int cls) { |
276 int k = repIndex(index[comp]); |
343 int rdx = classes[cls].firstItem; |
277 ItemT t; |
344 int idx = newItem(); |
278 |
345 |
279 int idx = items.size(); |
|
280 index.set(item, idx); |
346 index.set(item, idx); |
281 |
347 |
282 t.prevItem = k; |
348 laceItem(idx, rdx); |
283 t.nextItem = items[k].nextItem; |
349 |
284 items[items[k].nextItem].prevItem = idx; |
350 items[idx].item = item; |
285 items[k].nextItem = idx; |
351 items[idx].parent = rdx; |
286 |
352 |
287 t.item = item; |
353 ++classes[~(items[rdx].parent)].size; |
288 t.parent = k; |
|
289 |
|
290 --items[k].parent; |
|
291 |
|
292 items.push_back(t); |
|
293 } |
354 } |
294 |
355 |
295 /// \brief Clears the union-find data structure |
356 /// \brief Clears the union-find data structure |
296 /// |
357 /// |
297 /// Erase each item from the data structure. |
358 /// Erase each item from the data structure. |
298 void clear() { |
359 void clear() { |
299 items.clear(); |
360 items.clear(); |
300 firstClass = -1; |
361 firstClass = -1; |
301 } |
362 firstFreeItem = -1; |
302 |
363 } |
303 /// \brief Finds the leader of the component of the given element. |
364 |
304 /// |
365 /// \brief Finds the component of the given element. |
305 /// The method returns the leader of the component of the given element. |
366 /// |
306 const Item& find(const Item &item) const { |
367 /// The method returns the component id of the given element. |
307 return items[repIndex(index[item])].item; |
368 int find(const Item &item) const { |
|
369 return ~(items[repIndex(index[item])].parent); |
308 } |
370 } |
309 |
371 |
310 /// \brief Joining the component of element \e a and element \e b. |
372 /// \brief Joining the component of element \e a and element \e b. |
311 /// |
373 /// |
312 /// This is the \e union operation of the Union-Find structure. |
374 /// This is the \e union operation of the Union-Find structure. |
313 /// Joins the component of element \e a and component of |
375 /// Joins the component of element \e a and component of |
314 /// element \e b. If \e a and \e b are in the same component then |
376 /// element \e b. If \e a and \e b are in the same component then |
315 /// returns false else returns true. |
377 /// returns -1 else returns the remaining class. |
316 bool join(const Item& a, const Item& b) { |
378 int join(const Item& a, const Item& b) { |
317 |
379 |
318 int ak = repIndex(index[a]); |
380 int ak = repIndex(index[a]); |
319 int bk = repIndex(index[b]); |
381 int bk = repIndex(index[b]); |
320 |
382 |
321 if (ak == bk) { |
383 if (ak == bk) { |
322 return false; |
384 return -1; |
323 } |
385 } |
324 |
386 |
325 if ( items[ak].parent < items[bk].parent ) { |
387 int acx = ~(items[ak].parent); |
326 unlaceClass(bk); |
388 int bcx = ~(items[bk].parent); |
327 items[ak].parent += items[bk].parent; |
389 |
|
390 int rcx; |
|
391 |
|
392 if (classes[acx].size > classes[bcx].size) { |
|
393 classes[acx].size += classes[bcx].size; |
328 items[bk].parent = ak; |
394 items[bk].parent = ak; |
|
395 unlaceClass(bcx); |
|
396 rcx = acx; |
329 } else { |
397 } else { |
330 unlaceClass(ak); |
398 classes[bcx].size += classes[acx].size; |
331 items[bk].parent += items[ak].parent; |
|
332 items[ak].parent = bk; |
399 items[ak].parent = bk; |
|
400 unlaceClass(acx); |
|
401 rcx = bcx; |
333 } |
402 } |
334 spliceItems(ak, bk); |
403 spliceItems(ak, bk); |
335 |
404 |
336 return true; |
405 return rcx; |
337 } |
406 } |
338 |
407 |
339 /// \brief Returns the size of the component of element \e a. |
408 /// \brief Returns the size of the class. |
340 /// |
409 /// |
341 /// Returns the size of the component of element \e a. |
410 /// Returns the size of the class. |
342 int size(const Item &item) const { |
411 int size(int cls) const { |
343 return - items[repIndex(index[item])].parent; |
412 return classes[cls].size; |
344 } |
413 } |
345 |
414 |
346 /// \brief Splits up the component of the element. |
415 /// \brief Splits up the component. |
347 /// |
416 /// |
348 /// Splitting the component of the element into sigleton |
417 /// Splitting the component into singleton components (component |
349 /// components (component of size one). |
418 /// of size one). |
350 void split(const Item &item) { |
419 void split(int cls) { |
351 int k = repIndex(index[item]); |
420 int fdx = classes[cls].firstItem; |
352 int idx = items[k].nextItem; |
421 int idx = items[fdx].next; |
353 while (idx != k) { |
422 while (idx != fdx) { |
354 int next = items[idx].nextItem; |
423 int next = items[idx].next; |
|
424 |
|
425 singletonItem(idx); |
|
426 |
|
427 int cdx = newClass(); |
|
428 items[idx].parent = ~cdx; |
|
429 |
|
430 laceClass(cdx); |
|
431 classes[cdx].size = 1; |
|
432 classes[cdx].firstItem = idx; |
355 |
433 |
356 items[idx].parent = -1; |
|
357 items[idx].prevItem = idx; |
|
358 items[idx].nextItem = idx; |
|
359 |
|
360 items[idx].nextClass = firstClass; |
|
361 items[firstClass].prevClass = idx; |
|
362 firstClass = idx; |
|
363 |
|
364 idx = next; |
434 idx = next; |
365 } |
435 } |
366 |
436 |
367 items[idx].parent = -1; |
437 items[idx].prev = idx; |
368 items[idx].prevItem = idx; |
438 items[idx].next = idx; |
369 items[idx].nextItem = idx; |
439 |
370 |
440 classes[~(items[idx].parent)].size = 1; |
371 items[firstClass].prevClass = -1; |
441 |
372 } |
|
373 |
|
374 /// \brief Sets the given element to the leader element of its component. |
|
375 /// |
|
376 /// Sets the given element to the leader element of its component. |
|
377 void makeRep(const Item &item) { |
|
378 int nk = index[item]; |
|
379 int k = repIndex(nk); |
|
380 if (nk == k) return; |
|
381 |
|
382 if (items[k].prevClass != -1) { |
|
383 items[items[k].prevClass].nextClass = nk; |
|
384 } else { |
|
385 firstClass = nk; |
|
386 } |
|
387 if (items[k].nextClass != -1) { |
|
388 items[items[k].nextClass].prevClass = nk; |
|
389 } |
|
390 |
|
391 int idx = items[k].nextItem; |
|
392 while (idx != k) { |
|
393 items[idx].parent = nk; |
|
394 idx = items[idx].nextItem; |
|
395 } |
|
396 |
|
397 items[nk].parent = items[k].parent; |
|
398 items[k].parent = nk; |
|
399 } |
442 } |
400 |
443 |
401 /// \brief Removes the given element from the structure. |
444 /// \brief Removes the given element from the structure. |
402 /// |
445 /// |
403 /// Removes the element from its component and if the component becomes |
446 /// Removes the element from its component and if the component becomes |
404 /// empty then removes that component from the component list. |
447 /// empty then removes that component from the component list. |
405 /// |
448 /// |
406 /// \warning It is an error to remove an element which is not in |
449 /// \warning It is an error to remove an element which is not in |
407 /// the structure. |
450 /// the structure. |
408 void erase(const Item &item) { |
451 /// \warning This running time of this operation is proportional to the |
|
452 /// number of the items in this class. |
|
453 void erase(const Item& item) { |
409 int idx = index[item]; |
454 int idx = index[item]; |
410 if (rep(idx)) { |
455 int fdx = items[idx].next; |
411 int k = idx; |
456 |
412 if (items[k].parent == -1) { |
457 int cdx = classIndex(idx); |
413 unlaceClass(idx); |
458 if (idx == fdx) { |
414 return; |
459 unlaceClass(cdx); |
415 } else { |
460 items[idx].next = firstFreeItem; |
416 int nk = items[k].nextItem; |
461 firstFreeItem = idx; |
417 if (items[k].prevClass != -1) { |
462 return; |
418 items[items[k].prevClass].nextClass = nk; |
463 } else { |
419 } else { |
464 classes[cdx].firstItem = fdx; |
420 firstClass = nk; |
465 --classes[cdx].size; |
421 } |
466 items[fdx].parent = ~cdx; |
422 if (items[k].nextClass != -1) { |
467 |
423 items[items[k].nextClass].prevClass = nk; |
468 unlaceItem(idx); |
424 } |
469 idx = items[fdx].next; |
425 |
470 while (idx != fdx) { |
426 int l = items[k].nextItem; |
471 items[idx].parent = fdx; |
427 while (l != k) { |
472 idx = items[idx].next; |
428 items[l].parent = nk; |
473 } |
429 l = items[l].nextItem; |
|
430 } |
|
431 |
474 |
432 items[nk].parent = items[k].parent + 1; |
475 } |
433 } |
|
434 } else { |
|
435 |
|
436 int k = repIndex(idx); |
|
437 idx = items[k].nextItem; |
|
438 while (idx != k) { |
|
439 items[idx].parent = k; |
|
440 idx = items[idx].nextItem; |
|
441 } |
|
442 |
|
443 ++items[k].parent; |
|
444 } |
|
445 |
|
446 idx = index[item]; |
|
447 items[items[idx].prevItem].nextItem = items[idx].nextItem; |
|
448 items[items[idx].nextItem].prevItem = items[idx].prevItem; |
|
449 |
476 |
450 } |
477 } |
451 |
|
452 /// \brief Moves the given element to another component. |
|
453 /// |
|
454 /// This method moves the element \e a from its component |
|
455 /// to the component of \e comp. |
|
456 /// If \e a and \e comp are in the same component then |
|
457 /// it returns false otherwise it returns true. |
|
458 bool move(const Item &item, const Item &comp) { |
|
459 if (repIndex(index[item]) == repIndex(index[comp])) return false; |
|
460 erase(item); |
|
461 insert(item, comp); |
|
462 return true; |
|
463 } |
|
464 |
|
465 |
478 |
466 /// \brief Removes the component of the given element from the structure. |
479 /// \brief Removes the component of the given element from the structure. |
467 /// |
480 /// |
468 /// Removes the component of the given element from the structure. |
481 /// Removes the component of the given element from the structure. |
469 /// |
482 /// |
470 /// \warning It is an error to give an element which is not in the |
483 /// \warning It is an error to give an element which is not in the |
471 /// structure. |
484 /// structure. |
472 void eraseClass(const Item &item) { |
485 void eraseClass(int cls) { |
473 unlaceClass(repIndex(index[item])); |
486 int fdx = classes[cls].firstItem; |
|
487 unlaceClass(cls); |
|
488 items[items[fdx].prev].next = firstFreeItem; |
|
489 firstFreeItem = fdx; |
474 } |
490 } |
475 |
491 |
476 /// \brief Lemon style iterator for the representant items. |
492 /// \brief Lemon style iterator for the representant items. |
477 /// |
493 /// |
478 /// ClassIt is a lemon style iterator for the components. It iterates |
494 /// ClassIt is a lemon style iterator for the components. It iterates |
479 /// on the representant items of the classes. |
495 /// on the ids of the classes. |
480 class ClassIt { |
496 class ClassIt { |
481 public: |
497 public: |
482 /// \brief Constructor of the iterator |
498 /// \brief Constructor of the iterator |
483 /// |
499 /// |
484 /// Constructor of the iterator |
500 /// Constructor of the iterator |
485 ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) { |
501 ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) { |
486 idx = unionFind->firstClass; |
502 cdx = unionFind->firstClass; |
487 } |
503 } |
488 |
504 |
489 /// \brief Constructor to get invalid iterator |
505 /// \brief Constructor to get invalid iterator |
490 /// |
506 /// |
491 /// Constructor to get invalid iterator |
507 /// Constructor to get invalid iterator |
492 ClassIt(Invalid) : unionFind(0), idx(-1) {} |
508 ClassIt(Invalid) : unionFind(0), cdx(-1) {} |
493 |
509 |
494 /// \brief Increment operator |
510 /// \brief Increment operator |
495 /// |
511 /// |
496 /// It steps to the next representant item. |
512 /// It steps to the next representant item. |
497 ClassIt& operator++() { |
513 ClassIt& operator++() { |
498 idx = unionFind->items[idx].nextClass; |
514 cdx = unionFind->classes[cdx].next; |
499 return *this; |
515 return *this; |
500 } |
516 } |
501 |
517 |
502 /// \brief Conversion operator |
518 /// \brief Conversion operator |
503 /// |
519 /// |
504 /// It converts the iterator to the current representant item. |
520 /// It converts the iterator to the current representant item. |
505 operator const Item&() const { |
521 operator int() const { |
506 return unionFind->items[idx].item; |
522 return cdx; |
507 } |
523 } |
508 |
524 |
509 /// \brief Equality operator |
525 /// \brief Equality operator |
510 /// |
526 /// |
511 /// Equality operator |
527 /// Equality operator |
512 bool operator==(const ClassIt& i) { |
528 bool operator==(const ClassIt& i) { |
513 return i.idx == idx; |
529 return i.cdx == cdx; |
514 } |
530 } |
515 |
531 |
516 /// \brief Inequality operator |
532 /// \brief Inequality operator |
517 /// |
533 /// |
518 /// Inequality operator |
534 /// Inequality operator |
519 bool operator!=(const ClassIt& i) { |
535 bool operator!=(const ClassIt& i) { |
520 return i.idx != idx; |
536 return i.cdx != cdx; |
521 } |
537 } |
522 |
538 |
523 private: |
539 private: |
524 const UnionFindEnum* unionFind; |
540 const UnionFindEnum* unionFind; |
525 int idx; |
541 int cdx; |
526 }; |
542 }; |
527 |
543 |
528 /// \brief Lemon style iterator for the items of a component. |
544 /// \brief Lemon style iterator for the items of a component. |
529 /// |
545 /// |
530 /// ClassIt is a lemon style iterator for the components. It iterates |
546 /// ClassIt is a lemon style iterator for the components. It iterates |
584 return i.idx != idx; |
600 return i.idx != idx; |
585 } |
601 } |
586 |
602 |
587 private: |
603 private: |
588 const UnionFindEnum* unionFind; |
604 const UnionFindEnum* unionFind; |
589 int idx; |
605 int idx, fdx; |
590 }; |
606 }; |
591 |
607 |
592 }; |
608 }; |
593 |
609 |
|
610 /// \ingroup auxdat |
|
611 /// |
|
612 /// \brief A \e Extend-Find data structure implementation which |
|
613 /// is able to enumerate the components. |
|
614 /// |
|
615 /// The class implements an \e Extend-Find data structure which is |
|
616 /// able to enumerate the components and the items in a |
|
617 /// component. The data structure is a simplification of the |
|
618 /// Union-Find structure, and it does not allow to merge two components. |
|
619 /// |
|
620 /// \pre You need to add all the elements by the \ref insert() |
|
621 /// method. |
|
622 template <typename _ItemIntMap> |
|
623 class ExtendFindEnum { |
|
624 public: |
|
625 |
|
626 typedef _ItemIntMap ItemIntMap; |
|
627 typedef typename ItemIntMap::Key Item; |
|
628 |
|
629 private: |
|
630 |
|
631 ItemIntMap& index; |
|
632 |
|
633 struct ItemT { |
|
634 int cls; |
|
635 Item item; |
|
636 int next, prev; |
|
637 }; |
|
638 |
|
639 std::vector<ItemT> items; |
|
640 int firstFreeItem; |
|
641 |
|
642 struct ClassT { |
|
643 int firstItem; |
|
644 int next, prev; |
|
645 }; |
|
646 |
|
647 std::vector<ClassT> classes; |
|
648 |
|
649 int firstClass, firstFreeClass; |
|
650 |
|
651 int newClass() { |
|
652 if (firstFreeClass != -1) { |
|
653 int cdx = firstFreeClass; |
|
654 firstFreeClass = classes[cdx].next; |
|
655 return cdx; |
|
656 } else { |
|
657 classes.push_back(ClassT()); |
|
658 return classes.size() - 1; |
|
659 } |
|
660 } |
|
661 |
|
662 int newItem() { |
|
663 if (firstFreeItem != -1) { |
|
664 int idx = firstFreeItem; |
|
665 firstFreeItem = items[idx].next; |
|
666 return idx; |
|
667 } else { |
|
668 items.push_back(ItemT()); |
|
669 return items.size() - 1; |
|
670 } |
|
671 } |
|
672 |
|
673 public: |
|
674 |
|
675 /// \brief Constructor |
|
676 ExtendFindEnum(ItemIntMap& _index) |
|
677 : index(_index), items(), firstFreeItem(-1), |
|
678 classes(), firstClass(-1), firstFreeClass(-1) {} |
|
679 |
|
680 /// \brief Inserts the given element into a new component. |
|
681 /// |
|
682 /// This method creates a new component consisting only of the |
|
683 /// given element. |
|
684 int insert(const Item& item) { |
|
685 int cdx = newClass(); |
|
686 classes[cdx].prev = -1; |
|
687 classes[cdx].next = firstClass; |
|
688 firstClass = cdx; |
|
689 |
|
690 int idx = newItem(); |
|
691 items[idx].item = item; |
|
692 items[idx].cls = cdx; |
|
693 items[idx].prev = idx; |
|
694 items[idx].next = idx; |
|
695 |
|
696 classes[cdx].firstItem = idx; |
|
697 |
|
698 index.set(item, idx); |
|
699 |
|
700 return cdx; |
|
701 } |
|
702 |
|
703 /// \brief Inserts the given element into the given component. |
|
704 /// |
|
705 /// This methods inserts the element \e item a into the \e cls class. |
|
706 void insert(const Item& item, int cls) { |
|
707 int idx = newItem(); |
|
708 int rdx = classes[cls].firstItem; |
|
709 items[idx].item = item; |
|
710 items[idx].cls = cls; |
|
711 |
|
712 items[idx].prev = rdx; |
|
713 items[idx].next = items[rdx].next; |
|
714 items[items[rdx].next].prev = idx; |
|
715 items[rdx].next = idx; |
|
716 |
|
717 index.set(item, idx); |
|
718 } |
|
719 |
|
720 /// \brief Clears the union-find data structure |
|
721 /// |
|
722 /// Erase each item from the data structure. |
|
723 void clear() { |
|
724 items.clear(); |
|
725 classes.clear; |
|
726 firstClass = firstFreeClass = firstFreeItem = -1; |
|
727 } |
|
728 |
|
729 /// \brief Gives back the class of the \e item. |
|
730 /// |
|
731 /// Gives back the class of the \e item. |
|
732 int find(const Item &item) const { |
|
733 return items[index[item]].cls; |
|
734 } |
|
735 |
|
736 /// \brief Removes the given element from the structure. |
|
737 /// |
|
738 /// Removes the element from its component and if the component becomes |
|
739 /// empty then removes that component from the component list. |
|
740 /// |
|
741 /// \warning It is an error to remove an element which is not in |
|
742 /// the structure. |
|
743 void erase(const Item &item) { |
|
744 int idx = index[item]; |
|
745 int cdx = items[idx].cls; |
|
746 |
|
747 if (idx == items[idx].next) { |
|
748 if (classes[cdx].prev != -1) { |
|
749 classes[classes[cdx].prev].next = classes[cdx].next; |
|
750 } else { |
|
751 firstClass = classes[cdx].next; |
|
752 } |
|
753 if (classes[cdx].next != -1) { |
|
754 classes[classes[cdx].next].prev = classes[cdx].prev; |
|
755 } |
|
756 classes[cdx].next = firstFreeClass; |
|
757 firstFreeClass = cdx; |
|
758 } else { |
|
759 classes[cdx].firstItem = items[idx].next; |
|
760 items[items[idx].next].prev = items[idx].prev; |
|
761 items[items[idx].prev].next = items[idx].next; |
|
762 } |
|
763 items[idx].next = firstFreeItem; |
|
764 firstFreeItem = idx; |
|
765 |
|
766 } |
|
767 |
|
768 |
|
769 /// \brief Removes the component of the given element from the structure. |
|
770 /// |
|
771 /// Removes the component of the given element from the structure. |
|
772 /// |
|
773 /// \warning It is an error to give an element which is not in the |
|
774 /// structure. |
|
775 void eraseClass(int cdx) { |
|
776 int idx = classes[cdx].firstItem; |
|
777 items[items[idx].prev].next = firstFreeItem; |
|
778 firstFreeItem = idx; |
|
779 |
|
780 if (classes[cdx].prev != -1) { |
|
781 classes[classes[cdx].prev].next = classes[cdx].next; |
|
782 } else { |
|
783 firstClass = classes[cdx].next; |
|
784 } |
|
785 if (classes[cdx].next != -1) { |
|
786 classes[classes[cdx].next].prev = classes[cdx].prev; |
|
787 } |
|
788 classes[cdx].next = firstFreeClass; |
|
789 firstFreeClass = cdx; |
|
790 } |
|
791 |
|
792 /// \brief Lemon style iterator for the classes. |
|
793 /// |
|
794 /// ClassIt is a lemon style iterator for the components. It iterates |
|
795 /// on the ids of classes. |
|
796 class ClassIt { |
|
797 public: |
|
798 /// \brief Constructor of the iterator |
|
799 /// |
|
800 /// Constructor of the iterator |
|
801 ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) { |
|
802 cdx = extendFind->firstClass; |
|
803 } |
|
804 |
|
805 /// \brief Constructor to get invalid iterator |
|
806 /// |
|
807 /// Constructor to get invalid iterator |
|
808 ClassIt(Invalid) : extendFind(0), cdx(-1) {} |
|
809 |
|
810 /// \brief Increment operator |
|
811 /// |
|
812 /// It steps to the next representant item. |
|
813 ClassIt& operator++() { |
|
814 cdx = extendFind->classes[cdx].next; |
|
815 return *this; |
|
816 } |
|
817 |
|
818 /// \brief Conversion operator |
|
819 /// |
|
820 /// It converts the iterator to the current class id. |
|
821 operator int() const { |
|
822 return cdx; |
|
823 } |
|
824 |
|
825 /// \brief Equality operator |
|
826 /// |
|
827 /// Equality operator |
|
828 bool operator==(const ClassIt& i) { |
|
829 return i.cdx == cdx; |
|
830 } |
|
831 |
|
832 /// \brief Inequality operator |
|
833 /// |
|
834 /// Inequality operator |
|
835 bool operator!=(const ClassIt& i) { |
|
836 return i.cdx != cdx; |
|
837 } |
|
838 |
|
839 private: |
|
840 const ExtendFindEnum* extendFind; |
|
841 int cdx; |
|
842 }; |
|
843 |
|
844 /// \brief Lemon style iterator for the items of a component. |
|
845 /// |
|
846 /// ClassIt is a lemon style iterator for the components. It iterates |
|
847 /// on the items of a class. By example if you want to iterate on |
|
848 /// each items of each classes then you may write the next code. |
|
849 ///\code |
|
850 /// for (ClassIt cit(ufe); cit != INVALID; ++cit) { |
|
851 /// std::cout << "Class: "; |
|
852 /// for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) { |
|
853 /// std::cout << toString(iit) << ' ' << std::endl; |
|
854 /// } |
|
855 /// std::cout << std::endl; |
|
856 /// } |
|
857 ///\endcode |
|
858 class ItemIt { |
|
859 public: |
|
860 /// \brief Constructor of the iterator |
|
861 /// |
|
862 /// Constructor of the iterator. The iterator iterates |
|
863 /// on the class of the \c item. |
|
864 ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) { |
|
865 fdx = idx = extendFind->classes[cls].firstItem; |
|
866 } |
|
867 |
|
868 /// \brief Constructor to get invalid iterator |
|
869 /// |
|
870 /// Constructor to get invalid iterator |
|
871 ItemIt(Invalid) : extendFind(0), idx(-1) {} |
|
872 |
|
873 /// \brief Increment operator |
|
874 /// |
|
875 /// It steps to the next item in the class. |
|
876 ItemIt& operator++() { |
|
877 idx = extendFind->items[idx].next; |
|
878 if (fdx == idx) idx = -1; |
|
879 return *this; |
|
880 } |
|
881 |
|
882 /// \brief Conversion operator |
|
883 /// |
|
884 /// It converts the iterator to the current item. |
|
885 operator const Item&() const { |
|
886 return extendFind->items[idx].item; |
|
887 } |
|
888 |
|
889 /// \brief Equality operator |
|
890 /// |
|
891 /// Equality operator |
|
892 bool operator==(const ItemIt& i) { |
|
893 return i.idx == idx; |
|
894 } |
|
895 |
|
896 /// \brief Inequality operator |
|
897 /// |
|
898 /// Inequality operator |
|
899 bool operator!=(const ItemIt& i) { |
|
900 return i.idx != idx; |
|
901 } |
|
902 |
|
903 private: |
|
904 const ExtendFindEnum* extendFind; |
|
905 int idx, fdx; |
|
906 }; |
|
907 |
|
908 }; |
594 |
909 |
595 //! @} |
910 //! @} |
596 |
911 |
597 } //namespace lemon |
912 } //namespace lemon |
598 |
913 |