Szukaj…


Uwagi

Rodzina funkcji std::sort znajduje się w bibliotece algorithm .

Sortowanie kontenerów sekwencji z określonym porządkiem

Jeśli wartości w kontenerze mają już przeciążone pewne operatory, można użyć std::sort ze specjalnymi funktorami do sortowania w kolejności rosnącej lub malejącej:

C ++ 11
#include <vector>
#include <algorithm>
#include <functional>

std::vector<int> v = {5,1,2,4,3};

//sort in ascending order (1,2,3,4,5)
std::sort(v.begin(), v.end(), std::less<int>());

// Or just:
std::sort(v.begin(), v.end());

//sort in descending order (5,4,3,2,1)
std::sort(v.begin(), v.end(), std::greater<int>());

//Or just:
std::sort(v.rbegin(), v.rend());
C ++ 14

W C ++ 14 nie musimy podawać argumentu szablonu dla obiektów funkcji porównania, a zamiast tego pozwolić obiektowi wydedukować na podstawie tego, co zostanie przekazane:

std::sort(v.begin(), v.end(), std::less<>());     // ascending order
std::sort(v.begin(), v.end(), std::greater<>());  // descending order

Sortowanie kontenerów sekwencji według przeciążonego operatora mniej

Jeśli nie zostanie przekazana żadna funkcja porządkowania, std::sort uporządkuje elementy, wywołując operator< na parach elementów, które muszą zwrócić typ kontekstowo konwertowalny na bool (lub po prostu bool ). Podstawowe typy (liczby całkowite, zmiennoprzecinkowe, wskaźniki itp.) Mają już wbudowane operatory porównania.

Możemy przeciążać tego operatora, aby domyślne wywołanie sort działało na typach zdefiniowanych przez użytkownika.

// Include sequence containers
#include <vector>
#include <deque>
#include <list>

// Insert sorting algorithm
#include <algorithm>    

class Base {
 public:

    // Constructor that set variable to the value of v
    Base(int v): variable(v) {
    }
    
    // Use variable to provide total order operator less
    //`this` always represents the left-hand side of the compare.
    bool operator<(const Base &b) const { 
        return this->variable < b.variable;
    }
    
    int variable;
};

int main() {
    std::vector <Base> vector;
    std::deque <Base> deque;
    std::list <Base> list;
    
    // Create 2 elements to sort
    Base a(10);
    Base b(5);
    
    // Insert them into backs of containers
    vector.push_back(a);
    vector.push_back(b);
    
    deque.push_back(a);
    deque.push_back(b);
    
    list.push_back(a);
    list.push_back(b);
    
    // Now sort data using operator<(const Base &b) function
    std::sort(vector.begin(), vector.end());
    std::sort(deque.begin(), deque.end());
    // List must be sorted differently due to its design
    list.sort();

    return 0;
}

Sortowanie kontenerów sekwencji za pomocą funkcji porównania

// Include sequence containers
#include <vector>
#include <deque>
#include <list>

// Insert sorting algorithm
#include <algorithm>

class Base {
 public:

    // Constructor that set variable to the value of v
    Base(int v): variable(v) {
    }
       
    int variable;
};

bool compare(const Base &a, const Base &b) {
    return a.variable < b.variable;
}

int main() {
    std::vector <Base> vector;
    std::deque <Base> deque;
    std::list <Base> list;
    
    // Create 2 elements to sort
    Base a(10);
    Base b(5);
    
    // Insert them into backs of containers
    vector.push_back(a);
    vector.push_back(b);
    
    deque.push_back(a);
    deque.push_back(b);
    
    list.push_back(a);
    list.push_back(b);
    
    // Now sort data using comparing function
    std::sort(vector.begin(), vector.end(), compare);
    std::sort(deque.begin(), deque.end(), compare);
    list.sort(compare);

    return 0;
}

Sortowanie kontenerów sekwencji za pomocą wyrażeń lambda (C ++ 11)

C ++ 11
// Include sequence containers
#include <vector>
#include <deque>
#include <list>
#include <array>
#include <forward_list>

// Include sorting algorithm
#include <algorithm>

class Base {
 public:

    // Constructor that set variable to the value of v
    Base(int v): variable(v) {
    }
    
    int variable;
};


int main() {
    // Create 2 elements to sort
    Base a(10);
    Base b(5);
    
    // We're using C++11, so let's use initializer lists to insert items.
    std::vector <Base> vector = {a, b};
    std::deque <Base> deque = {a, b};
    std::list <Base> list = {a, b};
    std::array <Base, 2> array = {a, b};
    std::forward_list<Base> flist = {a, b};
    
    // We can sort data using an inline lambda expression
    std::sort(std::begin(vector), std::end(vector),
      [](const Base &a, const Base &b) { return a.variable < b.variable;});

    // We can also pass a lambda object as the comparator
    // and reuse the lambda multiple times
    auto compare = [](const Base &a, const Base &b) {
                     return a.variable < b.variable;};
    std::sort(std::begin(deque), std::end(deque), compare);
    std::sort(std::begin(array), std::end(array), compare);
    list.sort(compare);
    flist.sort(compare);

    return 0;
}

Pojemniki sortujące i sekwencyjne

std::sort , znaleziony w standardowym algorithm biblioteki nagłówka, jest standardowym algorytmem biblioteki do sortowania zakresu wartości, zdefiniowanym przez parę iteratorów. std::sort przyjmuje jako ostatni parametr funktor użyty do porównania dwóch wartości; w ten sposób określa kolejność. Zauważ, że std::sort nie jest stabilny .

Funkcja porównania musi narzucić ścisłe, słabe uporządkowanie elementów. Wystarczy proste porównanie mniejsze niż (lub większe niż).

Kontener z iteratorami o swobodnym dostępie można sortować za pomocą algorytmu std::sort :

C ++ 11
#include <vector>
#include <algorithm>

std::vector<int> MyVector = {3, 1, 2}

//Default comparison of <
std::sort(MyVector.begin(), MyVector.end());

std::sort wymaga, aby jego iteratory były iteratorami o dostępie swobodnym. Kontenery sekwencji std::list i std::forward_list (wymagające C ++ 11) nie zapewniają iteratorów o dostępie swobodnym, więc nie można ich używać ze std::sort . Jednak mają one funkcje członka sort które implementują algorytm sortowania, który działa z ich własnymi typami iteratorów.

C ++ 11
#include <list>
#include <algorithm>

std::list<int> MyList = {3, 1, 2}

//Default comparison of <
//Whole list only.
MyList.sort();

Ich funkcje sort członków zawsze sortują całą listę, więc nie mogą sortować podzakresu elementów. Ponieważ jednak list i forward_list mają operacje szybkiego łączenia, możesz wyodrębnić elementy do posortowania z listy, posortować je, a następnie umieścić z powrotem tam, gdzie były dość wydajne:

void sort_sublist(std::list<int>& mylist, std::list<int>::const_iterator start, std::list<int>::const_iterator end) {
    //extract and sort half-open sub range denoted by start and end iterator 
    std::list<int> tmp;
    tmp.splice(tmp.begin(), list, start, end);
    tmp.sort();
    //re-insert range at the point we extracted it from
    list.splice(end, tmp);
}

sortowanie za pomocą std :: map (rosnąco i malejąco)

Ten przykład sortuje elementy w porządku rosnącym klucza za pomocą mapy. W poniższym przykładzie możesz użyć dowolnego typu, w tym klasy, zamiast std::string .

#include <iostream>
#include <utility>
#include <map>

int main()
{
    std::map<double, std::string> sorted_map;
    // Sort the names of the planets according to their size
    sorted_map.insert(std::make_pair(0.3829, "Mercury"));
    sorted_map.insert(std::make_pair(0.9499, "Venus"));
    sorted_map.insert(std::make_pair(1,      "Earth"));
    sorted_map.insert(std::make_pair(0.532,  "Mars"));
    sorted_map.insert(std::make_pair(10.97,  "Jupiter"));
    sorted_map.insert(std::make_pair(9.14,   "Saturn"));
    sorted_map.insert(std::make_pair(3.981,  "Uranus"));
    sorted_map.insert(std::make_pair(3.865,  "Neptune"));

    for (auto const& entry: sorted_map)
    {
        std::cout << entry.second << " (" << entry.first << " of Earth's radius)" << '\n';
    }
}

Wynik:

Mercury (0.3829 of Earth's radius)
Mars (0.532 of Earth's radius)
Venus (0.9499 of Earth's radius)
Earth (1 of Earth's radius)
Neptune (3.865 of Earth's radius)
Uranus (3.981 of Earth's radius)
Saturn (9.14 of Earth's radius)
Jupiter (10.97 of Earth's radius)

Jeśli możliwe są wpisy z jednakowymi kluczami, użyj map multimap zamiast map (jak w poniższym przykładzie).

Aby posortować elementy w sposób malejący , zadeklaruj mapę odpowiednim funktorem porównawczym ( std::greater<> ):

#include <iostream>
#include <utility>
#include <map>

int main()
{
    std::multimap<int, std::string, std::greater<int>> sorted_map;
    // Sort the names of animals in descending order of the number of legs
    sorted_map.insert(std::make_pair(6,   "bug"));
    sorted_map.insert(std::make_pair(4,   "cat"));
    sorted_map.insert(std::make_pair(100, "centipede"));
    sorted_map.insert(std::make_pair(2,   "chicken"));
    sorted_map.insert(std::make_pair(0,   "fish"));
    sorted_map.insert(std::make_pair(4,   "horse"));
    sorted_map.insert(std::make_pair(8,   "spider"));

    for (auto const& entry: sorted_map)
    {
        std::cout << entry.second << " (has " << entry.first << " legs)" << '\n';
    }
}

Wynik

centipede (has 100 legs)
spider (has 8 legs)
bug (has 6 legs)
cat (has 4 legs)
horse (has 4 legs)
chicken (has 2 legs)
fish (has 0 legs)

Sortowanie wbudowanych tablic

Algorytm sort sortuje sekwencję zdefiniowaną przez dwa iteratory. To wystarczy, aby posortować wbudowaną tablicę (znaną również jako styl c).

C ++ 11
int arr1[] = {36, 24, 42, 60, 59};

// sort numbers in ascending order
sort(std::begin(arr1), std::end(arr1));

// sort numbers in descending order
sort(std::begin(arr1), std::end(arr1), std::greater<int>());

Przed wersją C ++ 11 koniec tablicy musiał być „obliczony” przy użyciu rozmiaru tablicy:

C ++ 11
// Use a hard-coded number for array size
sort(arr1, arr1 + 5);

// Alternatively, use an expression
const size_t arr1_size = sizeof(arr1) / sizeof(*arr1);
sort(arr1, arr1 + arr1_size);


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow