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
Défini dans l'en-tête <algorithm>
Signature d'appel
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) (depuis 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) (depuis C++20)
Types auxiliaires
template < class I1, class I2, class O >
using set_union_result = ranges:: in_in_out_result < I1, I2, O > ;
(3) (depuis C++20)

Construit une union triée commençant à result constituée de l'ensemble des éléments présents dans une ou les deux plages d'entrée triées [ first1 , last1 ) et [ first2 , last2 ) .

Si un élément est trouvé m fois dans [ first1 , last1 ) et n fois dans [ first2 , last2 ) , alors tous les m éléments seront copiés depuis [ first1 , last1 ) vers result , en préservant l'ordre, et ensuite exactement max ( n - m, 0 ) éléments seront copiés depuis [ first2 , last2 ) vers result , en préservant également l'ordre.

Le comportement est indéfini si

  • les plages d'entrée ne sont pas triées par rapport à comp et proj1 ou proj2 , respectivement, ou
  • la plage résultante chevauche l'une ou l'autre des plages d'entrée.
1) Les éléments sont comparés en utilisant la fonction de comparaison binaire donnée comp .
2) Identique à (1) , mais utilise r1 comme premier intervalle et r2 comme second intervalle, comme si on utilisait ranges:: begin ( r1 ) comme first1 , ranges:: end ( r1 ) comme last1 , ranges:: begin ( r2 ) comme first2 , et ranges:: end ( r2 ) comme last2 .

Les entités de type fonction décrites sur cette page sont des objets fonction d'algorithmes (informellement appelés niebloids ), c'est-à-dire :

Table des matières

Paramètres

first1, last1 - la paire itérateur-sentinelle définissant la première plage triée d'éléments en entrée
first2, last2 - la paire itérateur-sentinelle définissant la deuxième plage triée d'éléments en entrée
r1 - la première plage triée en entrée
r2 - la deuxième plage triée en entrée
result - le début de la plage de sortie
comp - comparaison à appliquer aux éléments projetés
proj1 - projection à appliquer aux éléments de la première plage
proj2 - projection à appliquer aux éléments de la deuxième plage

Valeur de retour

{ last1, last2, result_last } , où result_last est la fin de la plage construite.

Complexité

Au plus 2·(N 1 +N 2 )-1 comparaisons et applications de chaque projection, où N 1 et N 2 sont ranges:: distance ( first1, last1 ) et ranges:: distance ( first2, last2 ) , respectivement.

Notes

Cet algorithme effectue une tâche similaire à ranges::merge . 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 le traitement des valeurs des deux plages d'entrée qui sont équivalentes en comparaison (voir les notes sur LessThanComparable ). Si des valeurs équivalentes apparaissaient n fois dans la première plage et m fois dans la seconde, ranges::merge produirait toutes les n + m occurrences tandis que ranges::set_union produirait seulement std:: max ( n, m ) occurrences. Ainsi ranges::merge produit exactement (N 1 +N 2 ) valeurs et ranges::set_union peut en produire moins.

Implémentation possible

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 {};

Exemple

#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());
}

Sortie :

{ 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 }

Voir aussi

calcule la différence entre deux ensembles
(objet fonction algorithme)
calcule l'intersection de deux ensembles
(objet fonction algorithme)
calcule la différence symétrique entre deux ensembles
(objet fonction algorithme)
fusionne deux plages triées
(objet fonction algorithme)
renvoie true si une séquence est une sous-séquence d'une autre
(objet fonction algorithme)
calcule l'union de deux ensembles
(modèle de fonction)