Namespaces
Variants

std:: merge

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
merge
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Definiert in Header <algorithm>
template < class InputIt1, class InputIt2, class OutputIt >

OutputIt merge ( InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,

OutputIt d_first ) ;
(1) (constexpr seit 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) (seit 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 seit 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) (seit C++17)

Führt zwei sortierte Bereiche [ first1 , last1 ) und [ first2 , last2 ) in einem sortierten Bereich zusammen, beginnend bei d_first .

1) Wenn [ first1 , last1 ) oder [ first2 , last2 ) nicht sortiert ist bezüglich operator < (bis C++20) std:: less { } (seit C++20) , ist das Verhalten undefiniert.
3) Falls [ first1 , last1 ) oder [ first2 , last2 ) nicht in Bezug auf comp sortiert ist, ist das Verhalten undefiniert.
2,4) Gleich wie (1,3) , aber ausgeführt gemäß policy .
Diese Überladungen nehmen nur dann an der Überladungsauflösung teil, wenn alle folgenden Bedingungen erfüllt sind:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> ist true .

(bis C++20)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> ist true .

(seit C++20)

Diese Merge-Funktion ist stabil, was bedeutet, dass für äquivalente Elemente in den beiden ursprünglichen Bereichen die Elemente aus dem ersten Bereich (unter Beibehaltung ihrer ursprünglichen Reihenfolge) den Elementen aus dem zweiten Bereich (unter Beibehaltung ihrer ursprünglichen Reihenfolge) vorangehen.

Wenn der Ausgabebereich sich mit [ first1 , last1 ) oder [ first2 , last2 ) überschneidet, ist das Verhalten undefiniert.

Inhaltsverzeichnis

Parameter

first1, last1 - das Paar von Iteratoren, das den ersten Bereich der zu mergenden Elemente definiert
first2, last2 - das Paar von Iteratoren, das den zweiten Bereich der zu mergenden Elemente definiert
d_first - der Beginn des Zielbereichs
policy - die zu verwendende Ausführungsrichtlinie
comp - Vergleichsfunktionsobjekt (d.h. ein Objekt, das die Anforderungen von Compare erfüllt), das ​ true zurückgibt, wenn das erste Argument kleiner als (d.h. vor dem zweiten sortiert ist) das zweite.

Die Signatur der Vergleichsfunktion sollte äquivalent zu Folgendem sein:

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

Obwohl die Signatur kein const & benötigt, darf die Funktion die übergebenen Objekte nicht modifizieren und muss alle Werte der Typen (möglicherweise const) Type1 und Type2 unabhängig von der Wertkategorie akzeptieren können (daher ist Type1& nicht erlaubt , ebenso wenig wie Type1 , es sei denn, für Type1 ist eine Verschiebung äquivalent zu einer Kopie (seit C++11) ).
Die Typen Type1 und Type2 müssen so beschaffen sein, dass Objekte der Typen InputIt1 und InputIt2 dereferenziert und dann implizit sowohl zu Type1 als auch zu Type2 konvertiert werden können. ​

Typanforderungen
-
InputIt1, InputIt2 müssen die Anforderungen von LegacyInputIterator erfüllen.
-
ForwardIt1, ForwardIt2, ForwardIt3 müssen die Anforderungen von LegacyForwardIterator erfüllen.
-
OutputIt müssen die Anforderungen von LegacyOutputIterator erfüllen.
-
Compare müssen die Anforderungen von Compare erfüllen.

Rückgabewert

Ein Ausgabeiterator für das Element nach dem letzten kopierten Element.

Komplexität

Gegeben N 1 als std:: distance ( first1, last1 ) und N 2 als std:: distance ( first2, last2 ) :

1) Höchstens N 1 +N 2 -1 Vergleiche unter Verwendung von operator < (bis C++20) std:: less { } (seit C++20) .
2) O(N 1 +N 2 ) Vergleiche mit operator < (bis C++20) std:: less { } (seit C++20) .
3) Höchstens N 1 +N 2 -1 Anwendungen der Vergleichsfunktion comp .
4) O(N 1 +N 2 ) Anwendungen der Vergleichsfunktion comp .

Ausnahmen

Die Überladungen mit einem Template-Parameter namens ExecutionPolicy melden Fehler wie folgt:

  • Wenn die Ausführung einer als Teil des Algorithmus aufgerufenen Funktion eine Exception wirft und ExecutionPolicy einer der Standard-Policies ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsdefiniert.
  • Wenn der Algorithmus keinen Speicher allozieren kann, wird std::bad_alloc geworfen.

Mögliche Implementierung

Siehe auch die Implementierungen in libstdc++ und libc++ .

merge (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);
}
merge (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);
}
**Hinweis:** Der C++-Code in den `
`- und ``-Tags wurde gemäß den Anforderungen nicht übersetzt. Die Übersetzung beschränkt sich ausschließlich auf die deutschen Linkbeschriftungen "merge (1)" und "merge (3)", die als Teil der Tabellenüberschriften beibehalten wurden, da sie Funktionsbezeichnungen darstellen und gemäß den Vorgaben nicht übersetzt werden sollten.

Hinweise

Dieser Algorithmus führt eine ähnliche Aufgabe aus wie std:: set_union . Beide verarbeiten zwei sortierte Eingabebereiche und erzeugen eine sortierte Ausgabe mit Elementen aus beiden Eingaben. Der Unterschied zwischen diesen beiden Algorithmen liegt im Umgang mit Werten aus beiden Eingabebereichen, die als äquivalent verglichen werden (siehe Hinweise zu LessThanComparable ). Wenn äquivalente Werte n -mal im ersten Bereich und m -mal im zweiten Bereich auftreten, würde std::merge alle n + m Vorkommen ausgeben, während std::set_union nur std:: max ( n, m ) Vorkommen ausgibt. Daher gibt std::merge exakt std:: distance ( first1, last1 ) + std:: distance ( first2, last2 ) Werte aus, während std::set_union möglicherweise weniger erzeugt.

Beispiel

#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()
{
    // Vektoren mit Zufallszahlen füllen
    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("Ursprünglich:\nv1: ", v1);
    print("v2: ", v2);
    std::sort(v1.begin(), v1.end());
    std::sort(v2.begin(), v2.end());
    print("Nach Sortierung:\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("Nach Zusammenführung:\ndst: ", dst);
}

Mögliche Ausgabe:

Ursprünglich:
v1: 2 6 5 7 4 2 2 6 7 0
v2: 8 3 2 5 0 1 9 6 5 0
Nach Sortierung:
v1: 0 2 2 2 4 5 6 6 7 7
v2: 0 0 1 2 3 5 5 6 8 9
Nach Zusammenführung:
dst: 0 0 0 1 2 2 2 2 3 4 5 5 5 6 6 6 7 7 8 9

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
LWG 780 C++98 der Merge-Vorgang war nicht definiert definiert

Siehe auch

verbindet zwei geordnete Bereiche direkt
(Funktions-Template)
(C++11)
prüft, ob ein Bereich in aufsteigender Reihenfolge sortiert ist
(Funktions-Template)
berechnet die Vereinigung zweier Mengen
(Funktions-Template)
sortiert einen Bereich in aufsteigender Reihenfolge
(Funktions-Template)
sortiert einen Bereich von Elementen unter Beibehaltung der Reihenfolge gleicher Elemente
(Funktions-Template)
verbindet zwei sortierte Bereiche
(Algorithmus-Funktionsobjekt)