std::ranges::set_symmetric_difference, std::ranges::set_symmetric_difference_result
| Definido en el encabezado <algorithm>
|
||
| Firma de llamada |
||
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_symmetric_difference_result<I1, I2, O>
set_symmetric_difference( I1 first1, S1 last1, I2 first2, S2 last2,
O result, Comp comp = {},
Proj1 proj1 = {}, Proj2 proj2 = {} );
|
(1) | (desde 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_symmetric_difference_result<ranges::borrowed_iterator_t<R1>,
ranges::borrowed_iterator_t<R2>, O>
set_symmetric_difference( R1&& r1, R2&& r2, O result, Comp comp = {},
Proj1 proj1 = {}, Proj2 proj2 = {} );
|
(2) | (desde C++20) |
| Tipos auxiliares |
||
template< class I1, class I2, class O >
using set_symmetric_difference_result = ranges::in_in_out_result<I1, I2, O>;
|
(3) | (desde C++20) |
Calcula la diferencia simétrica de dos rangos ordenados: los elementos que se encuentran en cualquiera de los rangos, pero no en ambos, se copian al rango que comienza en result. El rango resultante también está ordenado.
Si algún elemento se encuentra m veces en [first1, last1) y n veces en [first2, last2), se copiará a result exactamente │m - n│ veces. Si m > n, entonces los últimos m - n de esos elementos se copian de [first1, last1), de lo contrario los últimos n - m elementos se copian de [first2, last2). El rango resultante no puede superponerse con ninguno de los rangos de entrada.
El comportamiento no está definido si
- los rangos de entrada no están ordenados con respecto a
compyproj1oproj2, respectivamente, o - el rango resultante se superpone con alguno de los rangos de entrada.
comp.r1 como primer rango y r2 como segundo rango, como si se utilizara ranges::begin(r1) como first1, ranges::end(r1) como last1, ranges::begin(r2) como first2, y ranges::end(r2) como last2.Las entidades similares a funciones descritas en esta página son objetos de función de algoritmo (conocidos informalmente como niebloids), es decir:
- No se pueden especificar listas explícitas de argumentos de plantilla al llamar a cualquiera de ellos.
- Ninguno de ellos es visible mediante búsqueda dependiente de argumentos.
- Cuando alguno de ellos se encuentra mediante búsqueda no calificada normal como el nombre a la izquierda del operador de llamada a función, la búsqueda dependiente de argumentos se inhibe.
Parámetros
| first1, last1 | - | el par iterador-centinela que define el primer rango de entrada ordenado de elementos |
| first2, last2 | - | el par iterador-centinela que define el segundo rango de entrada ordenado de elementos |
| r1 | - | el primer rango de entrada ordenado |
| r2 | - | el segundo rango de entrada ordenado |
| result | - | el inicio del rango de salida |
| comp | - | comparación a aplicar a los elementos proyectados |
| proj1 | - | proyección a aplicar a los elementos en el primer rango |
| proj2 | - | proyección a aplicar a los elementos en el segundo rango |
Valor de retorno
{ last1, last2, result_last } , donde result_last es el final del rango construido.
Complejidad
Como máximo 2·(N 1 +N 2 )-1 comparaciones y aplicaciones de cada proyección, donde N 1 y N 2 son ranges:: distance ( first1, last1 ) y ranges:: distance ( first2, last2 ) , respectivamente.
Implementación posible
struct set_symmetric_difference_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_symmetric_difference_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { while (!(first1 == last1 or first2 == last2)) { if (std::invoke(comp, std::invoke(proj1, *first1), std::invoke(proj2, *first2))) { *result = *first1; ++first1; ++result; } else if (std::invoke(comp, std::invoke(proj2, *first2), std::invoke(proj1, *first1))) { *result = *first2; ++first2; ++result; } else { ++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_symmetric_difference_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_symmetric_difference_fn set_symmetric_difference {}; |
Ejemplo
#include <algorithm> #include <iostream> #include <iterator> #include <vector> void visualize_this(const auto& v, int min = 1, int max = 9) { for (auto i {min}; i <= max; ++ i) { std::ranges::binary_search(v, i) ? std::cout << i : std::cout << '.'; std::cout << ' '; } std::cout << '\n'; } int main() { const auto in1 = {1, 3, 4, 6, 7, 9}; const auto in2 = {1, 4, 5, 6, 9}; std::vector<int> out {}; std::ranges::set_symmetric_difference(in1, in2, std::back_inserter(out)); visualize_this(in1); visualize_this(in2); visualize_this(out); }
Salida:
1 . 3 4 . 6 7 . 9 1 . . 4 5 6 . . 9 . . 3 . 5 . 7 . .
Véase también
(C++20) |
calcula la unión de dos conjuntos (objeto de función de algoritmo) |
(C++20) |
calcula la diferencia entre dos conjuntos (objeto de función de algoritmo) |
(C++20) |
calcula la intersección de dos conjuntos (objeto de función de algoritmo) |
(C++20) |
determina si una secuencia es una subsecuencia de otra (objeto de función de algoritmo) |
| calcula la diferencia simétrica entre dos conjuntos (plantilla de función) |