std::ranges:: set_union, std::ranges:: set_union_result
|
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,
|
(1) | (depuis C++20) |
|
template
<
ranges::
input_range
R1,
ranges::
input_range
R2,
std::
weakly_incrementable
O,
class
Comp
=
ranges::
less
,
|
(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.
Les entités de type fonction décrites sur cette page sont des objets fonction d'algorithmes (informellement appelés niebloids ), c'est-à-dire :
- Les listes d'arguments de modèle explicites ne peuvent pas être spécifiées lors de l'appel de l'une d'entre elles.
- Aucune d'entre elles n'est visible pour la recherche dépendante des arguments .
- Lorsque l'une d'entre elles est trouvée par la recherche non qualifiée normale comme nom à gauche de l'opérateur d'appel de fonction, la recherche dépendante des arguments est inhibée.
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
|
(C++20)
|
calcule la différence entre deux ensembles
(objet fonction algorithme) |
|
(C++20)
|
calcule l'intersection de deux ensembles
(objet fonction algorithme) |
|
(C++20)
|
calcule la différence symétrique entre deux ensembles
(objet fonction algorithme) |
|
(C++20)
|
fusionne deux plages triées
(objet fonction algorithme) |
|
(C++20)
|
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) |