Шаблонна функція std::set_intersection призначена для виявлення елементів, які спільні для двох послідовностей елементів, і реалізовує операцію перерізу множин. Оголошення функції виглядає наступним чином:
template <class InputIterator1,
class InputIterator2,
class OutputIterator>
OutputIterator set_intersection (InputIterator1 begin1,
InputIterator1 end1,
InputIterator2 begin2,
InputIterator2 end2,
OutputIterator result);
/* функція для іншого порядку елементів у контейнерах */
template <class InputIterator1,
class InputIterator2,
class OutputIterator,
class Compare>
OutputIterator set_intersection (InputIterator1 begin1,
InputIterator1 end1,
InputIterator2 begin2,
InputIterator2 end2,
OutputIterator result,
Compare comp) ;
Параметри-ітератори begin1 і end1 призначенні для обмеження послідовності елементів першої множини. Параметри-ітератори begin2 i end2 призначені для обмеження послідовності елементів доругої множини. Параметр ітератор result призначений для вказування першої позиції у контейнері, значення якого будуть замінюватись новими значеннями елементів, що отримуються під час виконання операції перерізу двох множин. Параметр comp являється бінарним придекатом, який використовується для порівняння двох елементів множин, і відповідно впливає на їхній порядок у всіх трьох послідовностях. Метод повертає ітератор, який вказує на елемент, що стоїть за останнім згенерованим елементом виконання операції, і вказує на ту ж послідовність що і result.
Елементи, що генеруються в результаті діяльності функції, копіюються тільки з першої множини. Перший варіант функції використовує оператор <. Елементи вважаються еквівалентними, якщо виконується умова (a<b || a>b) == false, або (comp(a,b) || comp(b,a)) == false.
Щоб використовувати дану функцію слід підключити у код файл algorithm
#include <algorithm> /* set_intersection і інші */
Приклади
Приклад #1
Розглянемо простий приклад використання даного методу. У якості вмістилища множин будемо використовувати контейнер vector. Для сортування послідовностей використаємо алгоритм sort. Для виведення елементів у термінал, будемо використовувати алгоритм for_each.
#include <algorithm> /* sort for_each set_intersection і інші */
#include <iostream> /* об'єкт cout */
#include <vector> /* клас vector */
using namespace std ; /* друкуємо усе без std */
/* шаблонна функція, яка виводить на екран
** переданий параметр разом з наступною
** крапкою з комою і пробілом (для алгоритму for_each) */
template <typename T> void print_elem_pred (T& e)
{ cout << e << "; " ; }
/* головна функція програми */
int main (int argc, char** argv)
{
/* створюємо піддослідні контейнери-вектори */
vector<int> v1, v2, resultv ;
/* заповнюємо джерельні вектори певними даними */
for (int iter=0; iter<10; ++iter)
{
v1.push_back (iter) ;
if ((iter%2)==0) { v2.push_back (iter*2) ; }
else { v2.push_back (iter) ; }
}
/* сортуємо, для певності, заповнені
** джерельні вектори */
sort (v1.begin(), v1.end()) ;
sort (v2.begin(), v2.end()) ;
/* виводимо вміст джерельних векторів
** на екран для наглядності */
cout << "v1: " ;
for_each (v1.begin(), v1.end(), print_elem_pred<int>) ;
cout << endl << "v2: ";
for_each (v2.begin(), v2.end(), print_elem_pred<int>) ;
cout << endl ;
/* створюємо достатньо місця для збереження нових елементів */
resultv.resize (v1.size() + v2.size(), 0) ;
/* виконуємо перетин двох множин
** разом з збереженням ітератора, який вказує на кінець
** новоствореної множини */
vector<int>::iterator new_end = set_intersection (v1.begin(), v1.end(),
v2.begin(), v2.end(),
resultv.begin()) ;
/* виводимо цільову множину елементів на екран */
cout << "v1 ∩ v2 : " ;
for_each (resultv.begin(), new_end, print_elem_pred<int>) ;
cout << endl ;
return 0 ;
}
Вивід програми наступний:
Приклад #2
Розглянемо приклад використання варіанту функції set_intersection з предикатом, для нового порядку елементів у множині.
#include <algorithm> /* sort for_each set_intersection і інші */
#include <functional> /* less more і інші */
#include <iostream> /* об'єкт cout */
#include <vector> /* об'єкт vector */
using namespace std ; /* друкуємо усе без std */
/* шаблонна функція, яка виводить на екран
** переданий параметр разом з наступною
** крапкою з комою і пробілом (для алгоритму for_each) */
template <typename T> void print_elem_pred (T& e)
{ cout << e << "; " ; }
/* головна функція програми */
int main (int argc, char** argv)
{
/* створюємо піддослідні контейнери-вектори */
vector<int> v1, v2, resultv ;
/* заповнюємо джерельні вектори певними даними */
for (int iter=0; iter<10; ++iter)
{
v1.push_back (iter) ;
if ((iter%2)==0) { v2.push_back (iter*2) ; }
else { v2.push_back (iter) ; }
}
/* створюємо об'єкт порівняння оператором > */
greater<int> greater_op ;
/* сортуємо, для певності, заповнені
** джерельні вектори pf за допомогою методу
** sort з предикатом оператора >,
** який міститься в функціональному об'єкті
** класу greater<int> */
sort (v1.begin(), v1.end(), greater_op) ;
sort (v2.begin(), v2.end(), greater_op) ;
/* виводимо вміст джерельних векторів
** на екран для наглядності */
cout << "v1: " ;
for_each (v1.begin(), v1.end(), print_elem_pred<int>) ;
cout << endl << "v2: ";
for_each (v2.begin(), v2.end(), print_elem_pred<int>) ;
cout << endl ;
/* створюємо достатньо місця для збереження нових елементів */
resultv.resize (v1.size() + v2.size(), 0) ;
/* виконуємо перетин двох множин
** разом з збереженням ітератора, який вказує на кінець
** новоствореної множини */
vector<int>::iterator new_end = set_intersection (v1.begin(), v1.end(),
v2.begin(), v2.end(),
resultv.begin(),
greater_op) ; /* оператор > */
/* виводимо цільову множину елементів на екран */
cout << "v1 ∩ v2: " ;
for_each (resultv.begin(), new_end, print_elem_pred<int>) ;
cout << endl ;
return 0 ;
}
Вивід програми наступний:
Якщо множини не були б сортованими одним оператором, ми б отримали некоректний результат.