gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Fix clear() function in ExtendFindEnum (#335), backport of [28c7ad6f8d91]
0 1 0
1.0
1 file changed with 1 insertions and 1 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
... ...
@@ -544,385 +544,385 @@
544 544
        return i.cdx != cdx;
545 545
      }
546 546

	
547 547
    private:
548 548
      const UnionFindEnum* unionFind;
549 549
      int cdx;
550 550
    };
551 551

	
552 552
    /// \brief LEMON style iterator for the items of a component.
553 553
    ///
554 554
    /// ClassIt is a lemon style iterator for the components. It iterates
555 555
    /// on the items of a class. By example if you want to iterate on
556 556
    /// each items of each classes then you may write the next code.
557 557
    ///\code
558 558
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
559 559
    ///   std::cout << "Class: ";
560 560
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
561 561
    ///     std::cout << toString(iit) << ' ' << std::endl;
562 562
    ///   }
563 563
    ///   std::cout << std::endl;
564 564
    /// }
565 565
    ///\endcode
566 566
    class ItemIt {
567 567
    public:
568 568
      /// \brief Constructor of the iterator
569 569
      ///
570 570
      /// Constructor of the iterator. The iterator iterates
571 571
      /// on the class of the \c item.
572 572
      ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) {
573 573
        fdx = idx = unionFind->classes[cls].firstItem;
574 574
      }
575 575

	
576 576
      /// \brief Constructor to get invalid iterator
577 577
      ///
578 578
      /// Constructor to get invalid iterator
579 579
      ItemIt(Invalid) : unionFind(0), idx(-1) {}
580 580

	
581 581
      /// \brief Increment operator
582 582
      ///
583 583
      /// It steps to the next item in the class.
584 584
      ItemIt& operator++() {
585 585
        idx = unionFind->items[idx].next;
586 586
        if (idx == fdx) idx = -1;
587 587
        return *this;
588 588
      }
589 589

	
590 590
      /// \brief Conversion operator
591 591
      ///
592 592
      /// It converts the iterator to the current item.
593 593
      operator const Item&() const {
594 594
        return unionFind->items[idx].item;
595 595
      }
596 596

	
597 597
      /// \brief Equality operator
598 598
      ///
599 599
      /// Equality operator
600 600
      bool operator==(const ItemIt& i) {
601 601
        return i.idx == idx;
602 602
      }
603 603

	
604 604
      /// \brief Inequality operator
605 605
      ///
606 606
      /// Inequality operator
607 607
      bool operator!=(const ItemIt& i) {
608 608
        return i.idx != idx;
609 609
      }
610 610

	
611 611
    private:
612 612
      const UnionFindEnum* unionFind;
613 613
      int idx, fdx;
614 614
    };
615 615

	
616 616
  };
617 617

	
618 618
  /// \ingroup auxdat
619 619
  ///
620 620
  /// \brief A \e Extend-Find data structure implementation which
621 621
  /// is able to enumerate the components.
622 622
  ///
623 623
  /// The class implements an \e Extend-Find data structure which is
624 624
  /// able to enumerate the components and the items in a
625 625
  /// component. The data structure is a simplification of the
626 626
  /// Union-Find structure, and it does not allow to merge two components.
627 627
  ///
628 628
  /// \pre You need to add all the elements by the \ref insert()
629 629
  /// method.
630 630
  template <typename _ItemIntMap>
631 631
  class ExtendFindEnum {
632 632
  public:
633 633

	
634 634
    typedef _ItemIntMap ItemIntMap;
635 635
    typedef typename ItemIntMap::Key Item;
636 636

	
637 637
  private:
638 638

	
639 639
    ItemIntMap& index;
640 640

	
641 641
    struct ItemT {
642 642
      int cls;
643 643
      Item item;
644 644
      int next, prev;
645 645
    };
646 646

	
647 647
    std::vector<ItemT> items;
648 648
    int firstFreeItem;
649 649

	
650 650
    struct ClassT {
651 651
      int firstItem;
652 652
      int next, prev;
653 653
    };
654 654

	
655 655
    std::vector<ClassT> classes;
656 656

	
657 657
    int firstClass, firstFreeClass;
658 658

	
659 659
    int newClass() {
660 660
      if (firstFreeClass != -1) {
661 661
        int cdx = firstFreeClass;
662 662
        firstFreeClass = classes[cdx].next;
663 663
        return cdx;
664 664
      } else {
665 665
        classes.push_back(ClassT());
666 666
        return classes.size() - 1;
667 667
      }
668 668
    }
669 669

	
670 670
    int newItem() {
671 671
      if (firstFreeItem != -1) {
672 672
        int idx = firstFreeItem;
673 673
        firstFreeItem = items[idx].next;
674 674
        return idx;
675 675
      } else {
676 676
        items.push_back(ItemT());
677 677
        return items.size() - 1;
678 678
      }
679 679
    }
680 680

	
681 681
  public:
682 682

	
683 683
    /// \brief Constructor
684 684
    ExtendFindEnum(ItemIntMap& _index)
685 685
      : index(_index), items(), firstFreeItem(-1),
686 686
        classes(), firstClass(-1), firstFreeClass(-1) {}
687 687

	
688 688
    /// \brief Inserts the given element into a new component.
689 689
    ///
690 690
    /// This method creates a new component consisting only of the
691 691
    /// given element.
692 692
    int insert(const Item& item) {
693 693
      int cdx = newClass();
694 694
      classes[cdx].prev = -1;
695 695
      classes[cdx].next = firstClass;
696 696
      if (firstClass != -1) {
697 697
        classes[firstClass].prev = cdx;
698 698
      }
699 699
      firstClass = cdx;
700 700

	
701 701
      int idx = newItem();
702 702
      items[idx].item = item;
703 703
      items[idx].cls = cdx;
704 704
      items[idx].prev = idx;
705 705
      items[idx].next = idx;
706 706

	
707 707
      classes[cdx].firstItem = idx;
708 708

	
709 709
      index.set(item, idx);
710 710

	
711 711
      return cdx;
712 712
    }
713 713

	
714 714
    /// \brief Inserts the given element into the given component.
715 715
    ///
716 716
    /// This methods inserts the element \e item a into the \e cls class.
717 717
    void insert(const Item& item, int cls) {
718 718
      int idx = newItem();
719 719
      int rdx = classes[cls].firstItem;
720 720
      items[idx].item = item;
721 721
      items[idx].cls = cls;
722 722

	
723 723
      items[idx].prev = rdx;
724 724
      items[idx].next = items[rdx].next;
725 725
      items[items[rdx].next].prev = idx;
726 726
      items[rdx].next = idx;
727 727

	
728 728
      index.set(item, idx);
729 729
    }
730 730

	
731 731
    /// \brief Clears the union-find data structure
732 732
    ///
733 733
    /// Erase each item from the data structure.
734 734
    void clear() {
735 735
      items.clear();
736
      classes.clear;
736
      classes.clear();
737 737
      firstClass = firstFreeClass = firstFreeItem = -1;
738 738
    }
739 739

	
740 740
    /// \brief Gives back the class of the \e item.
741 741
    ///
742 742
    /// Gives back the class of the \e item.
743 743
    int find(const Item &item) const {
744 744
      return items[index[item]].cls;
745 745
    }
746 746

	
747 747
    /// \brief Gives back a representant item of the component.
748 748
    ///
749 749
    /// Gives back a representant item of the component.
750 750
    Item item(int cls) const {
751 751
      return items[classes[cls].firstItem].item;
752 752
    }
753 753

	
754 754
    /// \brief Removes the given element from the structure.
755 755
    ///
756 756
    /// Removes the element from its component and if the component becomes
757 757
    /// empty then removes that component from the component list.
758 758
    ///
759 759
    /// \warning It is an error to remove an element which is not in
760 760
    /// the structure.
761 761
    void erase(const Item &item) {
762 762
      int idx = index[item];
763 763
      int cdx = items[idx].cls;
764 764

	
765 765
      if (idx == items[idx].next) {
766 766
        if (classes[cdx].prev != -1) {
767 767
          classes[classes[cdx].prev].next = classes[cdx].next;
768 768
        } else {
769 769
          firstClass = classes[cdx].next;
770 770
        }
771 771
        if (classes[cdx].next != -1) {
772 772
          classes[classes[cdx].next].prev = classes[cdx].prev;
773 773
        }
774 774
        classes[cdx].next = firstFreeClass;
775 775
        firstFreeClass = cdx;
776 776
      } else {
777 777
        classes[cdx].firstItem = items[idx].next;
778 778
        items[items[idx].next].prev = items[idx].prev;
779 779
        items[items[idx].prev].next = items[idx].next;
780 780
      }
781 781
      items[idx].next = firstFreeItem;
782 782
      firstFreeItem = idx;
783 783

	
784 784
    }
785 785

	
786 786

	
787 787
    /// \brief Removes the component of the given element from the structure.
788 788
    ///
789 789
    /// Removes the component of the given element from the structure.
790 790
    ///
791 791
    /// \warning It is an error to give an element which is not in the
792 792
    /// structure.
793 793
    void eraseClass(int cdx) {
794 794
      int idx = classes[cdx].firstItem;
795 795
      items[items[idx].prev].next = firstFreeItem;
796 796
      firstFreeItem = idx;
797 797

	
798 798
      if (classes[cdx].prev != -1) {
799 799
        classes[classes[cdx].prev].next = classes[cdx].next;
800 800
      } else {
801 801
        firstClass = classes[cdx].next;
802 802
      }
803 803
      if (classes[cdx].next != -1) {
804 804
        classes[classes[cdx].next].prev = classes[cdx].prev;
805 805
      }
806 806
      classes[cdx].next = firstFreeClass;
807 807
      firstFreeClass = cdx;
808 808
    }
809 809

	
810 810
    /// \brief LEMON style iterator for the classes.
811 811
    ///
812 812
    /// ClassIt is a lemon style iterator for the components. It iterates
813 813
    /// on the ids of classes.
814 814
    class ClassIt {
815 815
    public:
816 816
      /// \brief Constructor of the iterator
817 817
      ///
818 818
      /// Constructor of the iterator
819 819
      ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) {
820 820
        cdx = extendFind->firstClass;
821 821
      }
822 822

	
823 823
      /// \brief Constructor to get invalid iterator
824 824
      ///
825 825
      /// Constructor to get invalid iterator
826 826
      ClassIt(Invalid) : extendFind(0), cdx(-1) {}
827 827

	
828 828
      /// \brief Increment operator
829 829
      ///
830 830
      /// It steps to the next representant item.
831 831
      ClassIt& operator++() {
832 832
        cdx = extendFind->classes[cdx].next;
833 833
        return *this;
834 834
      }
835 835

	
836 836
      /// \brief Conversion operator
837 837
      ///
838 838
      /// It converts the iterator to the current class id.
839 839
      operator int() const {
840 840
        return cdx;
841 841
      }
842 842

	
843 843
      /// \brief Equality operator
844 844
      ///
845 845
      /// Equality operator
846 846
      bool operator==(const ClassIt& i) {
847 847
        return i.cdx == cdx;
848 848
      }
849 849

	
850 850
      /// \brief Inequality operator
851 851
      ///
852 852
      /// Inequality operator
853 853
      bool operator!=(const ClassIt& i) {
854 854
        return i.cdx != cdx;
855 855
      }
856 856

	
857 857
    private:
858 858
      const ExtendFindEnum* extendFind;
859 859
      int cdx;
860 860
    };
861 861

	
862 862
    /// \brief LEMON style iterator for the items of a component.
863 863
    ///
864 864
    /// ClassIt is a lemon style iterator for the components. It iterates
865 865
    /// on the items of a class. By example if you want to iterate on
866 866
    /// each items of each classes then you may write the next code.
867 867
    ///\code
868 868
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
869 869
    ///   std::cout << "Class: ";
870 870
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
871 871
    ///     std::cout << toString(iit) << ' ' << std::endl;
872 872
    ///   }
873 873
    ///   std::cout << std::endl;
874 874
    /// }
875 875
    ///\endcode
876 876
    class ItemIt {
877 877
    public:
878 878
      /// \brief Constructor of the iterator
879 879
      ///
880 880
      /// Constructor of the iterator. The iterator iterates
881 881
      /// on the class of the \c item.
882 882
      ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) {
883 883
        fdx = idx = extendFind->classes[cls].firstItem;
884 884
      }
885 885

	
886 886
      /// \brief Constructor to get invalid iterator
887 887
      ///
888 888
      /// Constructor to get invalid iterator
889 889
      ItemIt(Invalid) : extendFind(0), idx(-1) {}
890 890

	
891 891
      /// \brief Increment operator
892 892
      ///
893 893
      /// It steps to the next item in the class.
894 894
      ItemIt& operator++() {
895 895
        idx = extendFind->items[idx].next;
896 896
        if (fdx == idx) idx = -1;
897 897
        return *this;
898 898
      }
899 899

	
900 900
      /// \brief Conversion operator
901 901
      ///
902 902
      /// It converts the iterator to the current item.
903 903
      operator const Item&() const {
904 904
        return extendFind->items[idx].item;
905 905
      }
906 906

	
907 907
      /// \brief Equality operator
908 908
      ///
909 909
      /// Equality operator
910 910
      bool operator==(const ItemIt& i) {
911 911
        return i.idx == idx;
912 912
      }
913 913

	
914 914
      /// \brief Inequality operator
915 915
      ///
916 916
      /// Inequality operator
917 917
      bool operator!=(const ItemIt& i) {
918 918
        return i.idx != idx;
919 919
      }
920 920

	
921 921
    private:
922 922
      const ExtendFindEnum* extendFind;
923 923
      int idx, fdx;
924 924
    };
925 925

	
926 926
  };
927 927

	
928 928
  /// \ingroup auxdat
0 comments (0 inline)