Namespaces
Variants

std:: set_union

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)
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 set_union ( 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 set_union ( 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 set_union ( 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 set_union ( ExecutionPolicy && policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,

ForwardIt3 d_first, Compare comp ) ;
(4) (seit C++17)

Konstruiert eine sortierte Vereinigung beginnend bei d_first , bestehend aus der Menge der Elemente, die in einem oder beiden sortierten Bereichen [ first1 , last1 ) und [ first2 , last2 ) vorhanden sind.

Wenn [ first1 , last1 ) m Elemente enthält, die zueinander äquivalent sind, und [ first2 , last2 ) n Elemente enthält, die zu diesen äquivalent sind, dann werden alle m Elemente aus [ first1 , last1 ) in den Ausgabebereich kopiert, wobei die Reihenfolge erhalten bleibt, und anschließend die letzten std:: max ( n - m, 0 ) Elemente aus [ first2 , last2 ) in den Ausgabebereich kopiert, ebenfalls unter Beibehaltung der Reihenfolge.

1) Falls [ 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 bezüglich 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)

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 sortierten Eingabe- Bereich von Elementen definiert
first2, last2 - das Paar von Iteratoren, das den zweiten sortierten Eingabe- Bereich von Elementen definiert
d_first - der Anfang des Ausgabebereichs
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 nicht 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

Iterator hinter das Ende des konstruierten Bereichs.

Komplexität

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

1,2) Höchstens 2⋅(N 1 +N 2 )-1 Vergleiche unter Verwendung von operator < (bis C++20) std:: less { } (seit C++20) .
3,4) Höchstens 2⋅(N 1 +N 2 )-1 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 allokieren kann, wird std::bad_alloc geworfen.

Mögliche Implementierung

set_union (1)
template<class InputIt1, class InputIt2, class OutputIt>
OutputIt set_union(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++;
        else
        {
            *d_first = *first1;
            if (!(*first1 < *first2))
                ++first2;
            ++first1;
        }
    }
    return std::copy(first2, last2, d_first);
}
set_union (3)
template<class InputIt1, class InputIt2, class OutputIt, class Compare>
OutputIt set_union(InputIt1 first1, InputIt1 last1,
                   InputIt2 first2, InputIt2 last2, OutputIt d_first, Compare comp)
{
    for (; first1 != last1; ++d_first)
    {
        if (first2 == last2)
            // Bereich 2 abgeschlossen, Rest von Bereich 1 einfügen:
            return std::copy(first1, last1, d_first);
        if (comp(*first2, *first1))
            *d_first = *first2++;
        else
        {
            *d_first = *first1;
            if (!comp(*first1, *first2)) // Äquivalent => *first2 muss nicht eingefügt werden.
                ++first2;
            ++first1;
        }
    }
    // Bereich 1 abgeschlossen, Rest von Bereich 2 einfügen:
    return std::copy(first2, last2, d_first);
}

Hinweise

Dieser Algorithmus führt eine ähnliche Aufgabe aus wie std::merge es tut. 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 Anmerkungen zu LessThanComparable ). Wenn äquivalente Werte n Mal im ersten Bereich und m Mal im zweiten auftraten, würde std::merge alle n + m Vorkommen ausgeben, während std::set_union nur std:: max ( n, m ) ausgeben würde. Also gibt std::merge genau std:: distance ( first1, last1 ) + std:: distance ( first2, last2 ) Werte aus und std::set_union kann weniger erzeugen.

Beispiel

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
void println(const std::vector<int>& v)
{
    for (int i : v)
        std::cout << i << ' ';
    std::cout << '\n';
}
int main()
{
    std::vector<int> v1, v2, dest;
    v1 = {1, 2, 3, 4, 5};
    v2 = {3, 4, 5, 6, 7};
    std::set_union(v1.cbegin(), v1.cend(),
                   v2.cbegin(), v2.cend(),
                   std::back_inserter(dest));
    println(dest);
    dest.clear();
    v1 = {1, 2, 3, 4, 5, 5, 5};
    v2 = {3, 4, 5, 6, 7};
    std::set_union(v1.cbegin(), v1.cend(),
                   v2.cbegin(), v2.cend(),
                   std::back_inserter(dest));
    println(dest);
}

Ausgabe:

1 2 3 4 5 6 7 
1 2 3 4 5 5 5 6 7

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 291 C++98 es war nicht spezifiziert, wie äquivalente Elemente in den Eingabebereichen zu behandeln sind spezifiziert

Siehe auch

gibt true zurück, falls eine Sequenz eine Teilsequenz einer anderen ist
(Funktions-Template)
vereinigt zwei sortierte Bereiche
(Funktions-Template)
berechnet die Differenz zweier Mengen
(Funktions-Template)
berechnet den Schnitt zweier Mengen
(Funktions-Template)
berechnet die symmetrische Differenz zweier Mengen
(Funktions-Template)
berechnet die Vereinigung zweier Mengen
(Algorithmus-Funktionsobjekt)