Namespaces
Variants

std:: set_symmetric_difference

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)
set_symmetric_difference

Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Определено в заголовке <algorithm>
template < class InputIt1, class InputIt2, class OutputIt >

OutputIt set_symmetric_difference
( InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,

OutputIt d_first ) ;
(1) (constexpr начиная с C++20)
template < class ExecutionPolicy,

class ForwardIt1, class ForwardIt2, class ForwardIt3 >
ForwardIt3 set_symmetric_difference
( ExecutionPolicy && policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,

ForwardIt3 d_first ) ;
(2) (начиная с C++17)
template < class InputIt1, class InputIt2,

class OutputIt, class Compare >
OutputIt set_symmetric_difference
( InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,

OutputIt d_first, Compare comp ) ;
(3) (constexpr начиная с C++20)
template < class ExecutionPolicy,

class ForwardIt1, class ForwardIt2,
class ForwardIt3, class Compare >
ForwardIt3 set_symmetric_difference
( ExecutionPolicy && policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,

ForwardIt3 d_first, Compare comp ) ;
(4) (начиная с C++17)

Вычисляет симметрическую разность двух отсортированных диапазонов: элементы, которые находятся в одном из диапазонов, но не в обоих, копируются в диапазон, начинающийся с d_first . Выходной диапазон также является отсортированным.

Если [ first1 , last1 ) содержит m эквивалентных элементов и [ first2 , last2 ) содержит n эквивалентных им элементов, тогда std :: abs ( m - n ) из этих элементов будет скопировано в выходной диапазон с сохранением порядка:

  • если m > n , последние m - n элементов из диапазона [ first1 , last1 ) .
  • если m < n , последние n - m элементов из диапазона [ first2 , last2 ) .
1) Если [ first1 , last1 ) или [ first2 , last2 ) не является отсортированным относительно operator < (до C++20) std:: less { } (начиная с C++20) , поведение не определено.
3) Если [ first1 , last1 ) или [ first2 , last2 ) не отсортирован относительно comp , поведение не определено.
2,4) То же, что и (1,3) , но выполняется в соответствии с policy .
Эти перегрузки участвуют в разрешении перегрузки только при выполнении всех следующих условий:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> является true .

(до C++20)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> является true .

(начиная с C++20)

Если выходной диапазон пересекается с [ first1 , last1 ) или [ first2 , last2 ) , поведение не определено.

Содержание

Параметры

first1, last1 - пара итераторов, определяющих первый отсортированный диапазон элементов
first2, last2 - пара итераторов, определяющих второй отсортированный диапазон элементов
d_first - начало выходного диапазона
policy - политика выполнения для использования
comp - функция сравнения (т.е. объект, удовлетворяющий требованиям Compare ), которая возвращает ​ true если первый аргумент меньше (т.е. упорядочен перед ) второго.

Сигнатура функции сравнения должна быть эквивалентна следующей:

bool cmp ( const Type1 & a, const Type2 & b ) ;

Хотя сигнатура не обязана иметь const & , функция не должна модифицировать передаваемые ей объекты и должна быть способна принимать все значения типов (возможно const) Type1 и Type2 независимо от категории значения (следовательно, Type1& не допускается , как и Type1 , если для Type1 перемещение не эквивалентно копированию (since C++11) ).
Типы Type1 и Type2 должны быть такими, чтобы объекты типов InputIt1 и InputIt2 могли быть разыменованы и неявно преобразованы как в Type1 , так и в Type2 . ​

Требования к типам
-
InputIt1, InputIt2 должны удовлетворять требованиям LegacyInputIterator .
-
OutputIt должен удовлетворять требованиям LegacyOutputIterator .
-
ForwardIt1, ForwardIt2, ForwardIt3 должны удовлетворять требованиям LegacyForwardIterator .
-
Compare должен удовлетворять требованиям Compare .

Возвращаемое значение

Итератор за концом построенного диапазона.

Сложность

Пусть N 1 равно std:: distance ( first1, last1 ) и N 2 равно std:: distance ( first2, last2 ) :

1,2) Не более 2⋅(N 1 +N 2 )-1 сравнений с использованием operator < (до C++20) std:: less { } (начиная с C++20) .
3,4) Не более 2⋅(N 1 +N 2 )-1 применений функции сравнения comp .

Исключения

Перегрузки с параметром шаблона с именем ExecutionPolicy сообщают об ошибках следующим образом:

  • Если выполнение функции, вызванной как часть алгоритма, выбрасывает исключение и ExecutionPolicy является одним из стандартных политик , std::terminate вызывается. Для любой другой ExecutionPolicy поведение определяется реализацией.
  • Если алгоритму не удается выделить память, std::bad_alloc выбрасывается.

Возможная реализация

set_symmetric_difference (1)
template<class InputIt1, class InputIt2, class OutputIt>
OutputIt set_symmetric_difference(InputIt1 first1, InputIt1 last1,
                                  InputIt2 first2, InputIt2 last2, OutputIt d_first)
{
    while (first1 != last1)
    {
        if (first2 == last2)
            return std::copy(first1, last1, d_first);
        if (*first1 < *first2)
            *d_first++ = *first1++;
        else
        {
            if (*first2 < *first1)
                *d_first++ = *first2;
            else
                ++first1;
            ++first2;
        }
    }
    return std::copy(first2, last2, d_first);
}
set_symmetric_difference (3)
template<class InputIt1, class InputIt2, class OutputIt, class Compare>
OutputIt set_symmetric_difference(InputIt1 first1, InputIt1 last1,
                                  InputIt2 first2, InputIt2 last2,
                                  OutputIt d_first, Compare comp)
{
    while (first1 != last1)
    {
        if (first2 == last2)
            return std::copy(first1, last1, d_first);
        if (comp(*first1, *first2))
            *d_first++ = *first1++;
        else
        {
            if (comp(*first2, *first1))
                *d_first++ = *first2;
            else
                ++first1;
            ++first2;
        }
    }
    return std::copy(first2, last2, d_first);
}

Пример

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
    std::vector<int> v1{1, 2, 3, 4, 5, 6, 7, 8};
    std::vector<int> v2{5, 7, 9, 10};
    std::sort(v1.begin(), v1.end());
    std::sort(v2.begin(), v2.end());
    std::vector<int> v_symDifference;
    std::set_symmetric_difference(v1.begin(), v1.end(), v2.begin(), v2.end(),
                                  std::back_inserter(v_symDifference));
    for (int n : v_symDifference)
        std::cout << n << ' ';
    std::cout << '\n';
}

Вывод:

1 2 3 4 6 8 9 10

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам C++.

DR Applied to Behavior as published Correct behavior
LWG 291 C++98 не было указано, как обрабатывать эквивалентные элементы во входных диапазонах указано

Смотрите также

возвращает true если одна последовательность является подпоследовательностью другой
(шаблон функции)
вычисляет разность двух множеств
(шаблон функции)
вычисляет объединение двух множеств
(шаблон функции)
вычисляет пересечение двух множеств
(шаблон функции)
вычисляет симметрическую разность двух множеств
(функциональный объект алгоритма)