Sök…
Anmärkningar
Funktionen familjen std::sort
finns i algorithm
.
Sortera sekvensbehållare med specificerad beställning
Om värdena i en container har vissa operatörer som redan är överbelastade, kan std::sort
användas med specialiserade funktorer för att sortera i antingen stigande eller fallande ordning:
#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());
I C ++ 14 behöver vi inte tillhandahålla mallargumentet för jämförelsesfunktionsobjekten och låta i stället dra ifrån objektet baserat på vad det får passerat i:
std::sort(v.begin(), v.end(), std::less<>()); // ascending order
std::sort(v.begin(), v.end(), std::greater<>()); // descending order
Sortera sekvensbehållare efter överbelastad mindre operatör
Om ingen beställningsfunktion passeras kommer std::sort
att beställa elementen genom att ringa operator<
på par av element, som måste returnera en typ kontextuellt konvertibel till bool
(eller bara bool
). Bastyper (heltal, flottörer, pekare etc) har redan byggt i jämförelseaktörer.
Vi kan överbelasta denna operatör för att göra sort
arbetet med användardefinierade typer.
// 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;
}
Sortera sekvensbehållare med jämför-funktion
// 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;
}
Sortering av sekvensbehållare med lambda-uttryck (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;
}
Sortering och sekvensbehållare
std::sort
, som finns i standardbiblioteket header algorithm
, är en standardbibliotek algoritm för sortering av ett område av värden, som definieras av ett par av iteratorer. std::sort
tar som sista parameter en funktor som används för att jämföra två värden; det är så det bestämmer ordningen. Observera att std::sort
inte är stabilt .
Jämförelsefunktionen måste påföra elementen en strikt, svag ordning . En enkel jämförelse med mindre än (eller större än) räcker.
En behållare med iteratorer med slumpmässig åtkomst kan sorteras med std::sort
:
#include <vector>
#include <algorithm>
std::vector<int> MyVector = {3, 1, 2}
//Default comparison of <
std::sort(MyVector.begin(), MyVector.end());
std::sort
kräver att iteratorerna är iteratorer med slumpmässig åtkomst. Sekvensbehållarna std::list
och std::forward_list
(kräver C ++ 11) tillhandahåller inte iteratorer för slumpmässig åtkomst, så de kan inte användas med std::sort
. Men de har sort
som implementerar en sorteringsalgoritm som fungerar med sina egna iteratortyper.
#include <list>
#include <algorithm>
std::list<int> MyList = {3, 1, 2}
//Default comparison of <
//Whole list only.
MyList.sort();
Deras sort
medlemmar sort
alltid hela listan, så att de inte kan sortera ett delintervall av element. Men eftersom list
och forward_list
har snabba skarvningsoperationer kan du extrahera elementen som ska sorteras från listan, sortera dem och sedan fylla på dem där de var ganska effektivt så här:
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);
}
sortering med std :: karta (stigande och fallande)
Detta exempel sorterar element i stigande ordning för en nyckel med en karta. Du kan använda valfri typ, inklusive klass, istället för std::string
, i exemplet nedan.
#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';
}
}
Produktion:
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)
Om poster med lika knappar är möjliga, använd multimap
istället för map
(som i följande exempel).
För att sortera element på fallande sätt, förklara kartan med en korrekt jämförelse funktor ( 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';
}
}
Produktion
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)
Sortera inbyggda matriser
sort
sorterar en sekvens definierad av två iteratorer. Detta räcker för att sortera en inbyggd (även känd som c-stil) matris.
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>());
Innan C ++ 11 måste arrayens slut "beräknas" med hjälp av storleken på arrayen:
// 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);