Narzędzia użytkownika

Narzędzia witryny


partial_sort

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Previous revision
Next revision
Previous revision
partial_sort [2008/12/12 12:32]
alaskow1
partial_sort [2008/12/12 13:50] (aktualna)
alaskow1
Linia 34: Linia 34:
 ===== Opis algorytmu ===== ===== Opis algorytmu =====
  
-Przemieszcza elementy w kolekcji w zakresie [first, last) tak, że w zakresie [first, middle) zawiera najmniejsze elementy z całego zakresu sortowania kolekcji, a w zakresie [middle, last) znajdują się pozostałe, nieuporządkowane elementy.+Przemieszcza elementy w kolekcji w zakresie [**first****last**) tak, że w zakresie [**first****middle**) zawiera najmniejsze elementy z całego zakresu sortowania kolekcji, a w zakresie [**middle****last**) znajdują się pozostałe, nieuporządkowane elementy.
  
 Do porównywania obiektów w kolekcji funkcja wykorzystuje albo zdefiniowany dla obiektu operator mniejszości w pierwszej wersji funkcji, albo zewnętrzną funkcję/​funktor porównujący w wersji drugiej. Do porównywania obiektów w kolekcji funkcja wykorzystuje albo zdefiniowany dla obiektu operator mniejszości w pierwszej wersji funkcji, albo zewnętrzną funkcję/​funktor porównujący w wersji drugiej.
Linia 70: Linia 70:
     for (iter = first.begin();​ iter != first.end();​ ++iter)     for (iter = first.begin();​ iter != first.end();​ ++iter)
         cout << *iter << " ";         cout << *iter << " ";
 +
 +    /* out: 23 16 54 21 14 38 63 29 */
  
     /* Sortowanie kolekcji, do uzyskania 4 posortowanych elementów */     /* Sortowanie kolekcji, do uzyskania 4 posortowanych elementów */
Linia 79: Linia 81:
     for (iter = first.begin();​ iter != first.end();​ ++iter)     for (iter = first.begin();​ iter != first.end();​ ++iter)
         cout << *iter << " ";         cout << *iter << " ";
 +
 +    /* out: 14 16 21 23 54 38 63 29 */
 </​code>​ </​code>​
 +
 +==== Przykład drugi ====
 +
 +W tym przykładzie sortowana będzie kolekcja następujących obiektów, modelujących kartę pacjenta:
 +
 +<code cpp>
 +/* Rodzaj sortowania */
 +enum    SortBy {byName, byAge, byWeight};
 +
 +class   ​PatientCard {
 +    private:
 +        string ​         name;                   //​Nazwisko
 +        int             ​age; ​                   //Wiek
 +        double ​         weight; ​                //​Waga
 +
 +        static SortBy ​  ​sort; ​                  //​Rodzaj sortowania
 +    public:
 +        /* Konstruktor zerowy. */
 +        PatientCard() : name("​name"​),​ age(0), weight(0.0) {}
 +        /* Konstruktor inicjujący. */
 +        PatientCard(const string& _name, const int& _age, const double& _weight) :
 +            name(_name),​ age(_age), weight(_weight) {}
 +
 +        const string& ​  ​getName() const {       //​Zwraca nazwisko
 +            return name;
 +        }
 +
 +        const int       ​getAge() const {        //Zwraca wiek
 +            return age;
 +        }
 +
 +        const double ​   getWeight() const {     //​Zwraca wagę
 +            return weight;
 +        }
 +
 +        void    setSort(SortBy _sort) {         //​Ustala rodzaj sortowania
 +            sort    = _sort;
 +        }
 +
 +        /* Operator mniejszości,​ służący do porównywania w algorytmie. Porównuje
 +        odpowiednie pola dwóch obiektów, zwraca '​true',​ jeśli są uporządkowane
 +        rosnąco, i '​false',​ jeśli nie. Do wyboru pól do porównywania służy pole
 +        '​sort'​. */
 +        bool    operator<​(const PatientCard&​ _card) {
 +            switch (sort) {
 +                case    byName:
 +                    if (name.compare(_card.name) < 0)
 +                        return true;
 +                    break;
 +                case    byAge:
 +                    if (age < _card.age)
 +                        return true;
 +                    break;
 +                case    byWeight:
 +                    if (weight < _card.weight)
 +                        return true;
 +                    break;
 +                default:
 +                    return false;
 +            }
 +
 +            return false;
 +        };
 +
 +        /* Zaprzyjaźniony operator, pozwalający na wysłanie danych obiektu do
 +        strumienia wyjściowego. */
 +        friend ostream&​ operator<<​(ostream&​ _cout, const PatientCard&​ _card);
 +};
 +
 +SortBy ​ PatientCard::​sort ​  = byName; ​          //​Inicjacja statycznego pola '​sort'​
 +
 +/* Zaprzyjaźniony operator. */
 +ostream& ​   operator<<​(ostream&​ _cout, const PatientCard&​ _card) {
 +    _cout << _card.name << "​\n\t\twiek:​ " << _card.age << "​\twaga:​ " << _card.weight << endl;
 +
 +    return _cout;
 +}
 +
 +int main() {
 +    vector<​PatientCard> ​            ​second; ​    //​Kolekcja kart pacjenta
 +    vector<​PatientCard>::​iterator ​  ​iter2; ​     //Iterator do tej kolekcji
 +
 +    /* Wypełnienie kolekcji przykładowymi danymi */
 +    second.push_back(PatientCard("​Wilson",​ 32, 78.5));
 +    second.push_back(PatientCard("​Pearson",​ 27, 63.2));
 +    second.push_back(PatientCard("​Kingsley",​ 43, 89.0));
 +    second.push_back(PatientCard("​Smith",​ 18, 57.4));
 +    second.push_back(PatientCard("​Wiliams",​ 22, 82.1));
 +    second.push_back(PatientCard("​Crouch",​ 37, 102.6));
 +    second.push_back(PatientCard("​Michelson",​ 64, 96.4));
 +    second.push_back(PatientCard("​Bright",​ 54, 60.5));
 +
 +    vector<​PatientCard>​ third   = second; ​      //​Kolejne kolekcje
 +    vector<​PatientCard>​ fourth ​ = second;
 +
 +</​code>​
 +
 +=== Sortowanie wg wbudowanego operatora mniejszości ===
 +
 +Tu sortowanie odbywa się przy użyciu wbudowanego operatora mniejszości,​ który przy obecnym ustawieniu pola **sort** sortuje karty alfabetycznie. Chcemy zatem uzyskać trzy pierwsze karty:
 +
 +<code cpp>
 +partial_sort(second.begin(),​ second.begin() + 3, second.end());​
 +
 +/* out: Bright
 +                wiek: 54        waga: 60.5
 +        Crouch
 +                wiek: 37        waga: 102.6
 +        Kingsley
 +                wiek: 43        waga: 89
 +        Wiliams
 +                wiek: 22        waga: 82.1
 +        Smith... */
 +</​code>​
 +
 +=== Sortowanie wg zewnętrznej funkcji porównującej ===
 +
 +W tym przypadku zdefiniowano zewnętrzną funkcję, służącą do porównywania kart i sortowania ich według malejącej wagi:
 +
 +<code cpp>
 +bool    compareCard(const PatientCard&​ _a, const PatientCard&​ _b) {
 +    if (_a.getWeight() > _b.getWeight())
 +        return true;
 +    return false;
 +}
 +</​code>​
 +
 +Chcemy uzyskać cztery karty o największej wadze:
 +
 +<code cpp>
 +partial_sort(third.begin(),​ third.begin() + 4, third.end(),​ compareCard);​
 +
 +/* out: Crouch
 +                wiek: 37        waga: 102.6
 +        Michelson
 +                wiek: 64        waga: 96.4
 +        Kingsley
 +                wiek: 43        waga: 89
 +        Wiliams
 +                wiek: 22        waga: 82.1
 +        Smith
 +                wiek: 18        waga: 57.4
 +        Pearson
 +                wiek: 27        waga: 63.2
 +... */
 +</​code>​
 +
 +=== Sortowanie wg zdefiniowanego funktora ===
 +
 +Funktor, czyli obiekt funkcyjny, to taki obiekt, który ma zdefiniowany operator **operator()**. W ogólnym przypadku funktor może przechowywać stan, który może mieć wpływ na działanie tego operatora, w przeciwieństwie do stałej w działaniu funkcji porównującej. W tym przypadku jednak ograniczono się do najprostszego przypadku funktora:
 +
 +<code cpp>
 +class   ​functorCard {
 +    public:
 +        bool    operator()(const PatientCard&​ _a, const PatientCard&​ _b) {
 +            if (_a.getAge() > _b.getAge())
 +                return true;
 +
 +            return false;
 +        }
 +};
 +
 +</​code>​
 +
 +Jak widać, funktor umożliwia sortowanie wg malejącego wieku. Chcemy uzyskać pięć kart o największym wieku:
 +
 +<code cpp>
 +partial_sort(fourth.begin(),​ fourth.begin() + 5, fourth.end(),​ functorCard());​
 +
 +/* out: Michelson
 +                wiek: 64        waga: 96.4
 +        Bright
 +                wiek: 54        waga: 60.5
 +        Kingsley
 +                wiek: 43        waga: 89
 +        Crouch
 +                wiek: 37        waga: 102.6
 +        Wilson
 +                wiek: 32        waga: 78.5
 +        Smith
 +                wiek: 18        waga: 57.4
 +        Wiliams
 +                wiek: 22        waga: 82.1
 +... */
 +</​code>​
 +
 +===== Podsumowanie =====
 +
 +Algorytm **partial_sort** umożliwia wyodrębnienie **n** skrajnych elementów w danej kolekcji na podstawie pewnego kryterium, określonego za pomocą operatora mniejszości **operator<​**,​ funkcji porównującej bądź funktora. Dzięki temu, nie trzeba sortować całej kolekcji, wystarczy sortowanie do momentu uzyskania żądanej ilości elementów, co skraca sam czas trwania operacji.
 +
 +===== Źródła =====
 +
 +Plik źródłowy z przykładami:​ {{:​stl_algorytmy:​partial_sort2.cpp}}
 +
 +
 +----
 +
 +
 +//​[[alaskow1@stud.elka.pw.edu.pl|Artur Marcin Laskowski]] 2008/12/12 13:48//
  
partial_sort.1229081520.txt.gz · ostatnio zmienione: 2008/12/12 12:32 przez alaskow1