Namespaces
Variants

std::ranges:: set_union, std::ranges:: set_union_result

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
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
(Anmerkung: Der bereitgestellte HTML-Code enthält keinen übersetzbaren Text, da alle Tags leer sind. Die Struktur wurde gemäß den Anforderungen unverändert beibehalten.)
Definiert im Header <algorithm>
Aufrufsignatur
template < std:: input_iterator I1, std:: sentinel_for < I1 > S1,

std:: input_iterator I2, std:: sentinel_for < I2 > S2,
std:: weakly_incrementable O, class Comp = ranges:: less ,
class Proj1 = std:: identity , class Proj2 = std:: identity >
requires std:: mergeable < I1, I2, O, Comp, Proj1, Proj2 >
constexpr set_union_result < I1, I2, O >
set_union ( I1 first1, S1 last1, I2 first2, S2 last2,
O result, Comp comp = { } ,

Proj1 proj1 = { } , Proj2 proj2 = { } ) ;
(1) (seit C++20)
template < ranges:: input_range R1, ranges:: input_range R2,

std:: weakly_incrementable O, class Comp = ranges:: less ,
class Proj1 = std:: identity , class Proj2 = std:: identity >
requires std:: mergeable < ranges:: iterator_t < R1 > , ranges:: iterator_t < R2 > ,
O, Comp, Proj1, Proj2 >
constexpr set_union_result < ranges:: borrowed_iterator_t < R1 > ,
ranges:: borrowed_iterator_t < R2 > , O >
set_union ( R1 && r1, R2 && r2, O result, Comp comp = { } ,

Proj1 proj1 = { } , Proj2 proj2 = { } ) ;
(2) (seit C++20)
Hilfstypen
template < class I1, class I2, class O >
using set_union_result = ranges:: in_in_out_result < I1, I2, O > ;
(3) (seit C++20)

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

Wenn ein Element m mal in [ first1 , last1 ) und n mal in [ first2 , last2 ) gefunden wird, dann werden alle m Elemente aus [ first1 , last1 ) nach result kopiert, wobei die Reihenfolge erhalten bleibt, und anschließend genau max ( n - m, 0 ) Elemente aus [ first2 , last2 ) nach result kopiert, ebenfalls unter Beibehaltung der Reihenfolge.

Das Verhalten ist undefiniert, falls

  • die Eingabebereiche sind nicht sortiert in Bezug auf comp und proj1 oder proj2 , beziehungsweise, oder
  • der resultierende Bereich überschneidet sich mit einem der Eingabebereiche.
1) Elemente werden mit der gegebenen binären Vergleichsfunktion comp verglichen.
2) Gleich wie (1) , verwendet jedoch r1 als ersten Bereich und r2 als zweiten Bereich, als ob ranges:: begin ( r1 ) als first1 , ranges:: end ( r1 ) als last1 , ranges:: begin ( r2 ) als first2 , und ranges:: end ( r2 ) als last2 verwendet würde.

Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithm Function Objects (informell bekannt als Niebloids ), das heißt:

Inhaltsverzeichnis

Parameter

first1, last1 - das Iterator-Sentinel-Paar, das den ersten sortierten Eingabe- Bereich von Elementen definiert
first2, last2 - das Iterator-Sentinel-Paar, das den zweiten sortierten Eingabe- Bereich von Elementen definiert
r1 - der erste sortierte Eingabebereich
r2 - der zweite sortierte Eingabebereich
result - der Anfang des Ausgabebereichs
comp - Vergleich, der auf die projizierten Elemente angewendet wird
proj1 - Projektion, die auf die Elemente im ersten Bereich angewendet wird
proj2 - Projektion, die auf die Elemente im zweiten Bereich angewendet wird

Rückgabewert

{ last1, last2, result_last } , wobei result_last das Ende des konstruierten Bereichs ist.

Komplexität

Höchstens 2·(N 1 +N 2 )-1 Vergleiche und Anwendungen jeder Projektion, wobei N 1 und N 2 jeweils ranges:: distance ( first1, last1 ) und ranges:: distance ( first2, last2 ) entsprechen.

Hinweise

Dieser Algorithmus führt eine ähnliche Aufgabe aus wie ranges::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 Bereich auftreten, würde ranges::merge alle n + m Vorkommen ausgeben, während ranges::set_union nur std:: max ( n, m ) Vorkommen ausgeben würde. Daher gibt ranges::merge exakt (N 1 +N 2 ) Werte aus, und ranges::set_union kann weniger erzeugen.

Mögliche Implementierung

struct set_union_fn
{
    template<std::input_iterator I1, std::sentinel_for<I1> S1,
             std::input_iterator I2, std::sentinel_for<I2> S2,
             std::weakly_incrementable O, class Comp = ranges::less,
             class Proj1 = std::identity, class Proj2 = std::identity>
    requires std::mergeable<I1, I2, O, Comp, Proj1, Proj2>
    constexpr ranges::set_union_result<I1, I2, O>
        operator()(I1 first1, S1 last1, I2 first2, S2 last2,
                   O result, Comp comp = {},
                   Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        for (; !(first1 == last1 or first2 == last2); ++result)
        {
            if (std::invoke(comp, std::invoke(proj1, *first1), 
                                  std::invoke(proj2, *first2)))
            {
                *result = *first1;
                ++first1;
            }
            else if (std::invoke(comp, std::invoke(proj2, *first2),
                                       std::invoke(proj1, *first1)))
            {
                *result = *first2;
                ++first2;
            }
            else
            {
                *result = *first1;
                ++first1;
                ++first2;
            }
        }
        auto res1 = ranges::copy(std::move(first1), std::move(last1), std::move(result));
        auto res2 = ranges::copy(std::move(first2), std::move(last2), std::move(res1.out));
        return {std::move(res1.in), std::move(res2.in), std::move(res2.out)};
    }
    template<ranges::input_range R1, ranges::input_range R2,
             std::weakly_incrementable O, class Comp = ranges::less,
             class Proj1 = std::identity, class Proj2 = std::identity>
    requires std::mergeable<ranges::iterator_t<R1>, ranges::iterator_t<R2>,
                            O, Comp, Proj1, Proj2>
    constexpr ranges::set_union_result<ranges::borrowed_iterator_t<R1>,
                                       ranges::borrowed_iterator_t<R2>, O>
        operator()(R1&& r1, R2&& r2, O result, Comp comp = {},
                   Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        return (*this)(ranges::begin(r1), ranges::end(r1),
                       ranges::begin(r2), ranges::end(r2),
                       std::move(result), std::move(comp),
                       std::move(proj1), std::move(proj2));
    }
};
inline constexpr set_union_fn set_union {};

Beispiel

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
void print(const auto& in1, const auto& in2, auto first, auto last)
{
    std::cout << "{ ";
    for (const auto& e : in1)
        std::cout << e << ' ';
    std::cout << "} ∪ { ";
    for (const auto& e : in2)
        std::cout << e << ' ';
    std::cout << "} =\n{ ";
    while (!(first == last))
        std::cout << *first++ << ' ';
    std::cout << "}\n\n";
}
int main()
{
    std::vector<int> in1, in2, out;
    in1 = {1, 2, 3, 4, 5};
    in2 = {      3, 4, 5, 6, 7};
    out.resize(in1.size() + in2.size());
    const auto ret = std::ranges::set_union(in1, in2, out.begin());
    print(in1, in2, out.begin(), ret.out);
    in1 = {1, 2, 3, 4, 5, 5, 5};
    in2 = {      3, 4, 5, 6, 7};
    out.clear();
    out.reserve(in1.size() + in2.size());
    std::ranges::set_union(in1, in2, std::back_inserter(out));
    print(in1, in2, out.cbegin(), out.cend());
}

Ausgabe:

{ 1 2 3 4 5 } ∪ { 3 4 5 6 7 } =
{ 1 2 3 4 5 6 7 }
{ 1 2 3 4 5 5 5 } ∪ { 3 4 5 6 7 } =
{ 1 2 3 4 5 5 5 6 7 }

Siehe auch

berechnet die Differenz zwischen zwei Mengen
(Algorithmus-Funktionsobjekt)
berechnet die Schnittmenge zweier Mengen
(Algorithmus-Funktionsobjekt)
berechnet die symmetrische Differenz zwischen zwei Mengen
(Algorithmus-Funktionsobjekt)
führt zwei sortierte Bereiche zusammen
(Algorithmus-Funktionsobjekt)
gibt true zurück, wenn eine Sequenz eine Teilsequenz einer anderen ist
(Algorithmus-Funktionsobjekt)
berechnet die Vereinigungsmenge zweier Mengen
(Funktionstemplate)