Namespaces
Variants

std::merge

Depuis fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur plages (C++20)
Algorithmes contraints, p. ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modificatrices    
Opérations par lots
(C++17)
Opérations de recherche
Opérations de séquence modificatrices
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Opérations de tri et connexes
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur plages partitionnées)
Opérations d'ensemble (sur plages triées)
Opérations de fusion (sur plages triées)
Opérations de tas
Opérations de minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
Défini dans l'en-tête <algorithm>
template< class InputIt1, class InputIt2, class OutputIt >
OutputIt merge( InputIt1 first1, InputIt1 last1,
                InputIt2 first2, InputIt2 last2,
                OutputIt d_first );
(1) (constexpr depuis C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2, class ForwardIt3 >
ForwardIt3 merge( ExecutionPolicy&& policy,
                  ForwardIt1 first1, ForwardIt1 last1,
                  ForwardIt2 first2, ForwardIt2 last2,
                  ForwardIt3 d_first );
(2) (depuis C++17)
template< class InputIt1, class InputIt2,
          class OutputIt, class Compare >
OutputIt merge( InputIt1 first1, InputIt1 last1,
                InputIt2 first2, InputIt2 last2,
                OutputIt d_first, Compare comp );
(3) (constexpr depuis C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2,
          class ForwardIt3, class Compare >
ForwardIt3 merge( ExecutionPolicy&& policy,
                  ForwardIt1 first1, ForwardIt1 last1,
                  ForwardIt2 first2, ForwardIt2 last2,
                  ForwardIt3 d_first, Compare comp );
(4) (depuis C++17)

Fusionne deux plages triées [first1last1) et [first2last2) en une seule plage triée commençant à d_first.

1) Si [first1last1) ou [first2last2) n'est pas trié par rapport à operator<(jusqu'à C++20)std::less{}(depuis C++20), le comportement est indéfini.
3) Si [first1last1) ou [first2last2) n'est pas trié par rapport à comp, le comportement est indéfini.
2,4) Identique à (1,3), mais exécuté selon policy.
Ces surcharges participent à la résolution de surcharge uniquement si la valeur de l'expression suivante est true :

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(jusqu'à C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(depuis C++20)

Cette fonction de fusion est stable, ce qui signifie que pour les éléments équivalents dans les deux plages originales, les éléments de la première plage (en conservant leur ordre original) précèdent les éléments de la seconde plage (en conservant leur ordre original).

Si la plage de sortie chevauche [first1last1) ou [first2last2), le comportement est indéfini.

Paramètres

first1, last1 - la paire d'itérateurs définissant la première plage d'éléments à fusionner
first2, last2 - la paire d'itérateurs définissant la seconde plage d'éléments à fusionner
d_first - le début de la plage de destination
policy - la politique d'exécution à utiliser
comp - objet fonction de comparaison (c'est-à-dire un objet qui satisfait les exigences de Compare) qui retourne ​truetrue si le premier argument est inférieur au second (c'est-à-dire est ordonné avant

).

bool cmp(const Type1& a, const Type2& b);

La signature de la fonction de comparaison devrait être équivalente à la suivante : const&Bien que la signature n'ait pas besoin d'avoir Type1, la fonction ne doit pas modifier les objets qui lui sont passés et doit pouvoir accepter toutes les valeurs de type (éventuellement const) Type2 et indépendamment de la catégorie de valeurType1& (ainsi, n'est pas autoriséType1, ni Type1 sauf si pour un déplacement est équivalent à une copie(depuis C++11)
).Type1 Les types Type2 et InputIt1 doivent être tels que les objets de types InputIt2 et Type1 puissent être déréférencés puis convertis implicitement en Type2 et

. ​
Exigences de type
InputIt1, InputIt2- doit satisfaire les exigences de LegacyInputIterator
.
ForwardIt1, ForwardIt2, ForwardIt3- doit satisfaire les exigences de LegacyForwardIterator
.
OutputIt- doit satisfaire les exigences de LegacyOutputIterator
.
Compare- doit satisfaire les exigences de Compare

.

Valeur de retour

Un itérateur de sortie pointant sur l'élément après le dernier élément copié.

Complexité\(\scriptsize N_1\)N1std::distance(first1, last1) comme \(\scriptsize N_2\)N2std::distance(first2, last2) comme

: 1)\(\scriptsize N_1+N_2-1\)N1+N2-1operator< comparaisons utilisant std::less{}(jusqu'à C++20)(depuis C++20)
. \(\scriptsize O(N_1+N_2)\)O(N1+N2)operator< comparaisons utilisant std::less{}(jusqu'à C++20)(depuis C++20)
.3)\(\scriptsize N_1+N_2-1\)N1+N2-1comp applications de la fonction de comparaison
. \(\scriptsize O(N_1+N_2)\)O(N1+N2)comp applications de la fonction de comparaison

.

ExceptionsExecutionPolicyLes surcharges avec un paramètre template nommé

  • signalent les erreurs comme suit : ExecutionPolicySi l'exécution d'une fonction invoquée dans le cadre de l'algorithme lève une exception et que est l'une des politiques standard, std::terminateExecutionPolicy est appelé. Pour tout autre
  • , le comportement est défini par l'implémentation.Si l'algorithme échoue à allouer de la mémoire, std::bad_alloc

est lancée.

Implémentation possibleVoir aussi les implémentations dans libstdc++ et libc++

.
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);
}
merge (1)
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);
}

merge (3)

Notesstd::set_unionCet algorithme effectue une tâche similaire à celle de fait. Les deux consomment deux plages d'entrée triées et produisent une sortie triée avec les é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 se comparent comme équivalentes (voir les notes sur LessThanComparablen). Si des valeurs équivalentes apparaissaient m fois dans la première plage et std::merge fois dans la seconde, n + m produirait toutes les std::set_union occurrences tandis que std::max(n, m) ne produirait que std::merge occurrences. Ainsi std::distance(first1, last1) + std::distance(first2, last2) produit exactement std::set_union valeurs et

peut en produire moins.

#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()
{
    // fill the vectors with random numbers
    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("Originally:\nv1: ", v1);
    print("v2: ", v2);
    
    std::sort(v1.begin(), v1.end());
    std::sort(v2.begin(), v2.end());
    
    print("After sorting:\nv1: ", v1);
    print("v2: ", v2);
    
    // merge
    std::vector<int> dst;
    std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst));
    
    print("After merging:\ndst: ", dst);
}

Exécuter ce code

Originally:
v1: 2 6 5 7 4 2 2 6 7 0
v2: 8 3 2 5 0 1 9 6 5 0
After sorting:
v1: 0 2 2 2 4 5 6 6 7 7
v2: 0 0 1 2 3 5 5 6 8 9
After merging:
dst: 0 0 0 1 2 2 2 2 3 4 5 5 5 6 6 6 7 7 8 9

Sortie possible :

Rapports de défauts

Les rapports de défauts suivants modifiant le comportement ont été appliqués rétroactivement aux normes C++ précédemment publiées. DR Appliqué à Comportement publié
Comportement correct LWG 780 C++98 l'opération de fusion n'était pas définie

définie

inplace_merge
fusionne deux plages ordonnées sur place&(fonction template
ranges::inplace_merge
is_sorted
(C++11)
vérifie si une plage est triée&(fonction template
set_union
calcule l'union de deux ensembles&(fonction template
sort
trie une plage d'éléments&(fonction template
stable_sort
trie une plage d'éléments tout en préservant l'ordre relatif entre éléments équivalents&(fonction template
ranges::stable_sort
ranges::merge
(C++20)
fusionne deux plages triées
(objet fonction algorithme)