C++
Ordinamento
Ricerca…
Osservazioni
La famiglia di funzioni std::sort
si trova nella libreria degli algorithm
.
Ordinamento di contenitori di sequenza con ordinamento specificato
Se i valori in un contenitore hanno già alcuni operatori già sovraccaricati, std::sort
può essere utilizzato con i funtori specializzati per ordinare in ordine ascendente o discendente:
#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());
In C ++ 14, non è necessario fornire l'argomento modello per gli oggetti funzione di confronto e lasciare che l'oggetto si deduca in base a ciò che viene passato in:
std::sort(v.begin(), v.end(), std::less<>()); // ascending order
std::sort(v.begin(), v.end(), std::greater<>()); // descending order
Ordinare i contenitori della sequenza con un operatore meno carico
Se non viene passata alcuna funzione di ordinamento, std::sort
ordinerà gli elementi chiamando l' operator<
su coppie di elementi, che devono restituire un tipo contestualmente convertibile in bool
(o semplicemente bool
). I tipi di base (interi, float, puntatori, ecc.) Sono già stati creati negli operatori di confronto.
Possiamo sovraccaricare questo operatore per far funzionare la chiamata di sort
predefinita su tipi definiti dall'utente.
// 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;
}
Ordinare i contenitori della sequenza usando la funzione di confronto
// 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;
}
Ordinamento di contenitori di sequenza usando espressioni lambda (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;
}
Contenitori di ordinamento e sequenza
std::sort
, trovato algorithm
intestazione della libreria standard, è un algoritmo di libreria standard per l'ordinamento di un intervallo di valori, definito da una coppia di iteratori. std::sort
prende come ultimo parametro un funtore usato per confrontare due valori; questo è il modo in cui determina l'ordine. Nota che std::sort
non è stabile .
La funzione di confronto deve imporre un ordinamento rigoroso e debole sugli elementi. Un semplice confronto inferiore a (o maggiore di) sarà sufficiente.
Un contenitore con iteratori ad accesso casuale può essere ordinato usando l'algoritmo std::sort
:
#include <vector>
#include <algorithm>
std::vector<int> MyVector = {3, 1, 2}
//Default comparison of <
std::sort(MyVector.begin(), MyVector.end());
std::sort
richiede che i suoi iteratori siano iteratori ad accesso casuale. I contenitori di sequenza std::list
e std::forward_list
(che richiedono C ++ 11) non forniscono iteratori ad accesso casuale, quindi non possono essere usati con std::sort
. Tuttavia, essi hanno sort
funzioni membro che implementano un algoritmo di ordinamento che funziona con i propri tipi di iteratori.
#include <list>
#include <algorithm>
std::list<int> MyList = {3, 1, 2}
//Default comparison of <
//Whole list only.
MyList.sort();
Le funzioni di sort
membri sort
sempre l'intero elenco, in modo che non possano ordinare un sotto-intervallo di elementi. Tuttavia, dal momento che list
e forward_list
hanno operazioni di splicing rapido, è possibile estrarre gli elementi da ordinare dall'elenco, ordinarli, quindi reinserirli dove erano abbastanza efficienti in questo modo:
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);
}
ordinamento con std :: map (ascendente e discendente)
Questo esempio ordina gli elementi in ordine crescente di una chiave utilizzando una mappa. Puoi usare qualsiasi tipo, inclusa la classe, invece di std::string
, nell'esempio seguente.
#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';
}
}
Produzione:
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)
Se sono possibili voci con chiavi uguali, utilizzare multimap
anziché map
(come nell'esempio seguente).
Per ordinare gli elementi in modo discendente , dichiarare la mappa con un corretto functor di comparazione ( 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';
}
}
Produzione
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)
Ordinamento di array incorporati
L' sort
algoritmo ordina una sequenza definita da due iteratori. Questo è sufficiente per ordinare un array integrato (noto anche come stile c).
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>());
Prima di C ++ 11, la fine dell'array doveva essere "calcolata" usando la dimensione dell'array:
// 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);