std::nth_element
| Défini dans l'en-tête <algorithm>
|
||
template< class RandomIt >
void nth_element( RandomIt first, RandomIt nth, RandomIt last );
|
(1) | (constexpr depuis C++20) |
template< class ExecutionPolicy, class RandomIt >
void nth_element( ExecutionPolicy&& policy,
RandomIt first, RandomIt nth, RandomIt last );
|
(2) | (depuis C++17) |
template< class RandomIt, class Compare >
void nth_element( RandomIt first, RandomIt nth, RandomIt last,
Compare comp );
|
(3) | (constexpr depuis C++20) |
template< class ExecutionPolicy, class RandomIt, class Compare >
void nth_element( ExecutionPolicy&& policy,
RandomIt first, RandomIt nth, RandomIt last,
Compare comp );
|
(4) | (depuis C++17) |
nth_element réarrange les éléments dans [first, last) de sorte qu'après le réarrangement :
- L'élément pointé par
nthest remplacé par l'élément qui se trouverait à cette position si[first,last)était trié. - Pour tout itérateur
idans[first,nth)et tout itérateurjdans[nth,last), la condition suivante est satisfaite :
bool(*j < *i)(jusqu'à C++20)std::less{}(*j, *i)(depuis C++20) est false.bool(comp(*j, *i)) est false.
operator<(jusqu'à C++20)std::less{}(depuis C++20).comp.policy.true :
|
|
(jusqu'à C++20) |
|
|
(depuis C++20) |
Si l'une des conditions suivantes est satisfaite, le comportement est indéfini :
[first,nth)ou[nth,last)n'est pas une plage valide.
|
(jusqu'à C++11) |
|
(depuis C++11) |
Paramètres
| first, last | - | la paire d'itérateurs définissant la plage d'éléments pour le tri partiel |
| nth | - | itérateur à accès aléatoire définissant le point de partition du tri |
| policy | - | la politique d'exécution à utiliser |
| comp | - | objet fonction de comparaison (c'est-à-dire un objet qui satisfait aux exigences de Compare) qui renvoie true si le premier argument est inférieur (c'est-à-dire est ordonné avant) au second. La signature de la fonction de comparaison doit être équivalente à la suivante :
Bien que la signature n'ait pas besoin d'avoir |
| Exigences de type | ||
-RandomIt doit satisfaire aux exigences de LegacyRandomAccessIterator.
| ||
-Compare doit satisfaire aux exigences de Compare.
| ||
Complexité
Étant donné N comme last - first :
operator<(jusqu'à C++20)std::less{}(depuis C++20) en moyenne.operator<(jusqu'à C++20)std::less{}(depuis C++20), et O(N·log(N)) échanges.comp en moyenne.comp, et O(N·log(N)) échanges.Exceptions
Les surcharges avec un paramètre template nommé ExecutionPolicy signalent les erreurs comme suit :
- Si l'exécution d'une fonction invoquée dans le cadre de l'algorithme lève une exception et
ExecutionPolicyest l'une des politiques standard, std::terminate est appelé. Pour toute autreExecutionPolicy, le comportement est défini par l'implémentation. - Si l'algorithme échoue à allouer de la mémoire, std::bad_alloc est levé.
Implémentation possible
Voir aussi les implémentations dans libstdc++, libc++, et MSVC STL.
Notes
L'algorithme utilisé est généralement Introselect bien que d'autres algorithmes de sélection avec une complexité moyenne appropriée soient autorisés.
Exemple
#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <numeric>
#include <vector>
void printVec(const std::vector<int>& vec)
{
std::cout << "v = {";
for (char sep[]{0, ' ', 0}; const int i : vec)
std::cout << sep << i, sep[0] = ',';
std::cout << "};\n";
}
int main()
{
std::vector<int> v{5, 10, 6, 4, 3, 2, 6, 7, 9, 3};
printVec(v);
auto m = v.begin() + v.size() / 2;
std::nth_element(v.begin(), m, v.end());
std::cout << "\nThe median is " << v[v.size() / 2] << '\n';
// The consequence of the inequality of elements before/after the Nth one:
assert(std::accumulate(v.begin(), m, 0) < std::accumulate(m, v.end(), 0));
printVec(v);
// Note: comp function changed
std::nth_element(v.begin(), v.begin() + 1, v.end(), std::greater{});
std::cout << "\nThe second largest element is " << v[1] << '\n';
std::cout << "The largest element is " << v[0] << '\n';
printVec(v);
}
Résultat possible :
v = {5, 10, 6, 4, 3, 2, 6, 7, 9, 3};
The median is 6
v = {3, 2, 3, 4, 5, 6, 10, 7, 9, 6};
The second largest element is 9
The largest element is 10
v = {10, 9, 6, 7, 6, 3, 5, 4, 3, 2};
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement tel que publié | Comportement correct |
|---|---|---|---|
| LWG 2150 | C++98 | après le réarrangement, un seul élément avant nthdevait être non supérieur à un élément après nth
|
correction de l' exigence |
| LWG 2163 | C++98 | la surcharge (1) utilisait operator> pour comparer les éléments
|
changé en operator<
|
| P0896R4 | C++98 | [first, nth) et [nth, last)n'étaient pas requis d'être des plages valides |
le comportement est indéfini si l'un d'eux est invalide |
Voir aussi
| renvoie le plus grand élément d'une plage (modèle de fonction & objet fonction d'algorithme) | |
(C++20) |
|
| renvoie le plus petit élément d'une plage (modèle de fonction & objet fonction d'algorithme) | |
(C++20) |
|
| copie et trie partiellement une plage d'éléments (modèle de fonction & objet fonction d'algorithme) | |
(C++20) |
|
| trie une plage d'éléments tout en préservant l'ordre relatif entre éléments équivalents (modèle de fonction & objet fonction d'algorithme) | |
(C++20) |
|
| trie une plage d'éléments (modèle de fonction & objet fonction d'algorithme) | |
(C++20) |
|
(C++20) |
trouve le Nième élément si la plage était triée (objet fonction d'algorithme) |