std:: merge
|
Défini dans l'en-tête
<algorithm>
|
||
|
template
<
class
InputIt1,
class
InputIt2,
class
OutputIt
>
OutputIt merge
(
InputIt1 first1, InputIt1 last1,
|
(1) | (constexpr depuis C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2,
class
ForwardIt3
>
|
(2) | (depuis C++17) |
|
template
<
class
InputIt1,
class
InputIt2,
class
OutputIt,
class
Compare
>
|
(3) | (constexpr depuis C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2,
|
(4) | (depuis C++17) |
Fusionne deux plages triées
[
first1
,
last1
)
et
[
first2
,
last2
)
en une seule plage triée commençant à
d_first
.
[
first1
,
last1
)
ou
[
first2
,
last2
)
n'est pas
trié
par rapport à
operator
<
(jusqu'à C++20)
std::
less
{
}
(depuis C++20)
, le comportement est indéfini.
[
first1
,
last1
)
ou
[
first2
,
last2
)
n'est pas trié par rapport à
comp
, le comportement est indéfini.
|
std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> est true . |
(jusqu'en C++20) |
|
std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> est true . |
(depuis C++20) |
Cette fonction de fusion est stable, ce qui signifie que pour les éléments équivalents dans les deux plages d'origine, les éléments de la première plage (préservant leur ordre d'origine) précèdent les éléments de la seconde plage (préservant leur ordre d'origine).
Si la plage de sortie chevauche
[
first1
,
last1
)
ou
[
first2
,
last2
)
, le comportement est indéfini.
Table des matières |
Paramètres
| first1, last1 | - | la paire d'itérateurs définissant le premier intervalle d'éléments à fusionner |
| first2, last2 | - | la paire d'itérateurs définissant le second intervalle d'éléments à fusionner |
| d_first | - | le début de l'intervalle de destination |
| 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
) le second.
La signature de la fonction de comparaison doit être équivalente à ce qui suit : bool cmp ( const Type1 & a, const Type2 & b ) ;
Bien que la signature n'ait pas besoin d'avoir
const
&
, la fonction ne doit pas modifier les objets qui lui sont passés et doit pouvoir accepter toutes les valeurs de type (éventuellement const)
|
| Exigences de type | ||
-
InputIt1, InputIt2
doivent satisfaire aux exigences de
LegacyInputIterator
.
|
||
-
ForwardIt1, ForwardIt2, ForwardIt3
doivent satisfaire aux exigences de
LegacyForwardIterator
.
|
||
-
OutputIt
doivent satisfaire aux exigences de
LegacyOutputIterator
.
|
||
-
Compare
doivent satisfaire aux exigences de
Compare
.
|
||
Valeur de retour
Un itérateur de sortie vers l'élément situé après le dernier élément copié.
Complexité
Soit N 1 défini comme std:: distance ( first1, last1 ) et N 2 défini comme std:: distance ( first2, last2 ) :
Exceptions
Les surcharges avec un paramètre de modèle 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 que
ExecutionPolicyfait partie des politiques standard , std::terminate est appelé. Pour tout autreExecutionPolicy, le comportement est défini par l'implémentation. - Si l'algorithme ne parvient pas à allouer de la mémoire, std::bad_alloc est levé.
Implémentation possible
Voir également les implémentations dans libstdc++ et libc++ .
| fusionner (1) |
|---|
template<class InputIt1, class InputIt2, class OutputIt> OutputIt merge(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first) { for (; first1 != last1; ++d_first) { if (first2 == last2) return std::copy(first1, last1, d_first); if (*first2 < *first1) { *d_first = *first2; ++first2; } else { *d_first = *first1; ++first1; } } return std::copy(first2, last2, d_first); } |
| fusionner (3) |
template<class InputIt1, class InputIt2, class OutputIt, class Compare> OutputIt merge(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first, Compare comp) { for (; first1 != last1; ++d_first) { if (first2 == last2) return std::copy(first1, last1, d_first); if (comp(*first2, *first1)) { *d_first = *first2; ++first2; } else { *d_first = *first1; ++first1; } } return std::copy(first2, last2, d_first); } |
Notes
Cet algorithme effectue une tâche similaire à celle de
std::
set_union
. Les deux consomment deux plages d'entrée triées et produisent une sortie triée avec des éléments des deux entrées. La différence entre ces deux algorithmes réside dans la gestion des valeurs des deux plages d'entrée qui sont équivalentes (voir les notes sur
LessThanComparable
). Si des valeurs équivalentes apparaissaient
n
fois dans la première plage et
m
fois dans la seconde,
std::merge
produirait toutes les
n
+
m
occurrences tandis que
std::set_union
ne produirait que
std::
max
(
n, m
)
. Ainsi,
std::merge
produit exactement
std::
distance
(
first1, last1
)
+
std::
distance
(
first2, last2
)
valeurs et
std::set_union
peut en produire moins.
Exemple
#include <algorithm> #include <functional> #include <iostream> #include <iterator> #include <random> #include <vector> auto print = [](const auto rem, const auto& v) { std::cout << rem; std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n'; }; int main() { // remplir les vecteurs avec des nombres aléatoires std::random_device rd; std::mt19937 mt(rd()); std::uniform_int_distribution<> dis(0, 9); std::vector<int> v1(10), v2(10); std::generate(v1.begin(), v1.end(), std::bind(dis, std::ref(mt))); std::generate(v2.begin(), v2.end(), std::bind(dis, std::ref(mt))); print("Originalement :\nv1 : ", v1); print("v2 : ", v2); std::sort(v1.begin(), v1.end()); std::sort(v2.begin(), v2.end()); print("Après tri :\nv1 : ", v1); print("v2 : ", v2); // fusion std::vector<int> dst; std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst)); print("Après fusion :\ndst : ", dst); }
Sortie possible :
Originalement : v1 : 2 6 5 7 4 2 2 6 7 0 v2 : 8 3 2 5 0 1 9 6 5 0 Après tri : v1 : 0 2 2 2 4 5 6 6 7 7 v2 : 0 0 1 2 3 5 5 6 8 9 Après fusion : dst : 0 0 0 1 2 2 2 2 3 4 5 5 5 6 6 6 7 7 8 9
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 | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 780 | C++98 | l'opération de fusion n'était pas définie | définie |
Voir aussi
|
fusionne deux plages ordonnées en place
(modèle de fonction) |
|
|
(C++11)
|
vérifie si une plage est triée par ordre croissant
(modèle de fonction) |
|
calcule l'union de deux ensembles
(modèle de fonction) |
|
|
trie une plage par ordre croissant
(modèle de fonction) |
|
|
trie une plage d'éléments en préservant l'ordre entre les éléments égaux
(modèle de fonction) |
|
|
(C++20)
|
fusionne deux plages triées
(objet fonction algorithme) |