Namespaces
Variants

std:: set_intersection

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_intersection
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_intersection ( 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_intersection ( 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_intersection ( 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_intersection ( ExecutionPolicy && policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,

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

Создает отсортированный диапазон, начинающийся с d_first , состоящий из элементов, которые присутствуют в обоих отсортированных диапазонах [ first1 , last1 ) и [ first2 , last2 ) .

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

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_intersection (1)
template<class InputIt1, class InputIt2, class OutputIt>
OutputIt set_intersection(InputIt1 first1, InputIt1 last1,
                          InputIt2 first2, InputIt2 last2, OutputIt d_first)
{
    while (first1 != last1 && first2 != last2)
    {
        if (*first1 < *first2)
            ++first1;
        else
        {
            if (!(*first2 < *first1))
                *d_first++ = *first1++; // *first1 and *first2 are equivalent.
            ++first2;
        }
    }
    return d_first;
}
set_intersection (3)
template<class InputIt1, class InputIt2, class OutputIt, class Compare>
OutputIt set_intersection(InputIt1 first1, InputIt1 last1,
                          InputIt2 first2, InputIt2 last2, OutputIt d_first, Compare comp)
{
    while (first1 != last1 && first2 != last2)
    {
        if (comp(*first1, *first2))
            ++first1;
        else
        {
            if (!comp(*first2, *first1))
                *d_first++ = *first1++; // *first1 and *first2 are equivalent.
            ++first2;
        }
    }
    return d_first;
}

Пример

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

Вывод:

5 7 7

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

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

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

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

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