Алгоритмы для работы с множествами
Содержание
- 1. Алгоритм includes. Определить, может ли одна последовательность быть подпоследовательностью другой
- 2. Алгоритм set_union. Объединение последовательностей
- 3. Алгоритм set_intersection. Определить общее между последовательностями (сечение множеств)
- 4. Алгоритм set_difference. Разница последовательностей (разница множеств)
- 5. Алгоритм set_symmetric_difference. Симметричная разница. Получить элементы, которых нет в обеих последовательностях
- Связанные темы
Поиск на других ресурсах:
1. Алгоритм includes. Определить, может ли одна последовательность быть подпоследовательностью другой
Алгоритм includes проверяет, содержит ли один отсортированный диапазон все элементы второго отсортированного диапазона. Порядок сортировки и критерий эквивалентности элементов можно задать бинарным предикатом.
Распространенные реализации алгоритма следующие
template <class InputIterator1, class InputIterator2> bool includes( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template <class InputIterator1, class InputIterator2, class Compare> bool includes( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare pred );
здесь
- first1, last1 – итераторы ввода, задающие первый упорядоченный диапазон;
- first2, last2 – итераторы ввода, задающие второй упорядоченный диапазон;
- pred – бинарный предикат, задающий критерий эквивалентности элементов.
Пример 1.
#include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std; void main() { // Алгоритм includes. // Определить, содержит ли массив V1 подмассив V2 // 1. Создать массив из 10 чисел vector<int> V1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // 2. Создать подмассив из 4 чисел vector<int> V2 = { 5, 6, 7, 8 }; // 3. Вызвать алгоритм includes bool res = includes(V1.begin(), V1.end(), V2.begin(), V2.end()); // 4. Обработать результат if (res) cout << "V2 <= V1" << endl; else cout << "V2 != V1" << endl; }
Результат
V2 <= V1
Пример 2.
В этом примере используется функция Include().
#include <iostream> #include <vector> #include <queue> #include <list> #include <algorithm> #include <functional> using namespace std; // Функция сравнения элементов bool Include(int item1, int item2) { // Такое условие требует, чтобы последовательности были упорядочены return item1 < item2; } void main() { // Алгоритм includes. // Определить, содержит ли массив V1 подмассив V2 // 1. Создать массив из 10 чисел vector<int> V1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // 2. Создать подмассив из 3 чисел vector<int> V2 = { 5, 7, 9, 11 }; // 3. Вызвать алгоритм includes - версия 2 bool res = includes(V1.begin(), V1.end(), V2.begin(), V2.end(), Include); // 4. Обработать результат if (res) cout << "V2 <= V1" << endl; else cout << "V2 != V1" << endl; }
Результат
V2 != V1
⇑
2. Алгоритм set_union. Объединение последовательностей
Алгоритм set_union реализует объединение двух упорядоченных последовательностей в одну результирующую по принципу объединения множеств. Встречающийся элемент дважды добавляется к результирующей последовательности только один раз. Критерий отбора может быть задан специальной функцией-предикатом. Например
{ 2, 4, 8, 9 } И { 2, 3, 8, 11 } => { 2, 3, 4, 8, 9, 11 }
Согласно документации, распространенные реализации алгоритма имеют следующие объявления
template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_union( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result ); template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_union( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare pred );
здесь
- first1, last1 – итераторы ввода, задающие границы первой упорядоченной последовательности;
- first2, last2 – итераторы ввода, задающие границы второй упорядоченной последовательности;
- result – итератор вывода, задающий позицию первого элемента в диапазоне назначения. В этом диапазоне объединяются два выходных диапазона.
Пример.
#include <iostream> #include <algorithm> #include <list> using namespace std; int main() { // Алгоритм set_union - объединение последовательностей // 1. Создать два списка чисел list<int> L1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; list<int> L2 = { 2, 3, 4, 11, 50 }; // 2. Создать результирующий список – размер списка как сумма размеров двух исходных списков list<int> L3(L1.size() + L2.size()); // 3. Объявить итератор, который будет указывать следующий за последним элемент результирующего списка L3 list<int>::iterator itRes; // 4. Определение разности между последовательностями без применения предиката // 4.1. Вызвать алгоритм set_difference //itRes = set_symmetric_difference(L1.begin(), L1.end(), L2.begin(), L2.end(), L3.begin()); itRes = set_union(L1.begin(), L1.end(), L2.begin(), L2.end(), L3.begin()); // 4.2. Вывести результат – значение итератора в пределах [L3.begin() ... itRes) list<int>::iterator it = L3.begin(); while (it != itRes) { cout << *it << " "; it++; } cout << endl; }
Результат
0 1 2 3 4 5 6 7 8 9 11 50
⇑
3. Алгоритм set_intersection. Определить общее между последовательностями (сечение множеств)
Алгоритм set_intersection создает последовательность, содержащую общие элементы двух исходных последовательностей. Последовательности должны быть отсортированы. Критерий сортировки может быть задан бинарным предикатом. Например
{ 2, 4, 8, 9 } З { 2, 3, 8, 11 } => { 2, 8 }
Распространенные реализации алгоритма имеют следующие объявления
template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_intersection( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_intersection( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare pred);
здесь
- first1, last1 – итераторы ввода, задающие диапазон значений первой последовательности;
- first2, last2 – итераторы ввода, задающие пределы второй последовательности;
- result – итератор ввода, задающий позицию первого элемента в результирующей последовательности;
- pred – объект функции-предиката, задающий условие, когда один элемент меньше другого.
Пример.
#include <iostream> #include <algorithm> #include <list> using namespace std; int main() { // Алгоритм set_intersection - получение общего между последовательностями // 1. Создать два списка чисел list<int> L1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; list<int> L2 = { 2, 3, 11, 50 }; // 2. Создать результирующий список – размер списка как сумма размеров двух исходных списков list<int> L3(L1.size() + L2.size()); // 3. Объявить итератор, который будет указывать на следующий за последним // элемент результирующего списка L3. list<int>::iterator itRes; // 4. Определение разности между последовательностями без применения предиката // 4.1. Вызвать алгоритм set_difference itRes = set_intersection(L1.begin(), L1.end(), L2.begin(), L2.end(), L3.begin()); // 4.2. Вывести результат - значение итератора в пределах [L3.begin() ... itRes) list<int>::iterator it = L3.begin(); while (it != itRes) { cout << *it << " "; it++; } cout << endl; }
Результат
2 3
⇑
4. Алгоритм set_difference. Разница последовательностей (разница множеств)
Алгоритм set_difference формирует новую последовательность на основе двух сортированных последовательностей по правилу разности этих последовательностей. В этом случае в первой последовательности остаются только элементы, которых нет во второй последовательности. Например:
{ 2, 4, 8, 9 } - { 2, 3, 8, 11 } => { 4, 9 }
Распространенные реализации алгоритма имеют следующие объявления
template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_difference( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result ); template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_difference( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare pred );
здесь
- first1, last1 – итераторы ввода, задающие пределы первой последовательности;
- first2, last2 – итераторы ввода, задающие пределы второй последовательности;
- result – итератор вывода, указывающий на начало результирующей последовательности;
- pred – предикат, который задает условие, когда один элемент меньше другого.
Пример.
#include <iostream> #include <algorithm> #include <list> using namespace std; int main() { // Алгоритм set_difference - разница множеств // 1. Создать два списка чисел list<int> L1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; list<int> L2 = { 2, 3, 11, 50 }; // 2. Создать результирующий список – размер списка как сумма размеров двух исходных списков list<int> L3(L1.size() + L2.size()); // 3. Объявить итератор, который будет указывать на следующий за последним элемент результирующего списка L3 list<int>::iterator itRes; // 4. Определение различий между последовательностями без применения предиката // 4.1. Вызвать алгоритм set_difference itRes = set_difference(L1.begin(), L1.end(), L2.begin(), L2.end(), L3.begin()); // 4.2. Вывести результат – значение итератора в пределах [L3.begin() ... itRes) list<int>::iterator it = L3.begin(); while (it != itRes) { cout << *it << " "; it++; } cout << endl; }
Результат
0 1 4 5 6 7 8 9
⇑
5. Алгоритм set_symmetric_difference. Симметричная разница. Получить элементы, которых нет в обеих последовательностях
Алгоритм set_symmetric_difference возвращает последовательность элементов на основе двух сортированных последовательностей. В результирующую последовательность входят элементы, являющиеся либо в первой последовательности, либо во второй последовательности. Общие элементы не входят в результирующую последовательность. Например
{ 2, 4, 6, 8 } D { 2, 3, 4, 5 } => { 3, 5, 6, 8 }
Согласно документации объявления наиболее распространенных реализаций алгоритма имеет вид
template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_symmetric_difference( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result ); template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_symmetric_difference( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare pred );
здесь
- first1, last1 – итераторы ввода, задающие пределы первой последовательности;
- first2, last2 – итераторы ввода, задающие пределы второй последовательности;
- result – итератор вывода, указывающий на начало результирующей последовательности;
- pred – предикат, который задает условие, когда один элемент меньше другого.
Пример.
#include <iostream> #include <algorithm> #include <list> using namespace std; int main() { // Алгоритм set_symmetric_difference - симметричная разница двух последовательностей // 1. Создать два списка чисел list<int> L1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; list<int> L2 = { 2, 3, 4, 11, 50 }; // 2. Создать результирующий список – размер списка как сумма размеров двух исходных списков list<int> L3(L1.size() + L2.size()); // 3. Объявить итератор, который будет указывать на следующий за последним элемент // результирующего списка L3. list<int>::iterator itRes; // 4. Определение разницы между последовательностями без применения предиката // 4.1. Вызвать алгоритм set_difference itRes = set_symmetric_difference(L1.begin(), L1.end(), L2.begin(), L2.end(), L3.begin()); // 4.2. Вывести результат – значение итератора в пределах [L3.begin() ... itRes) list<int>::iterator it = L3.begin(); while (it != itRes) { cout << *it << " "; it++; } cout << endl; }
Результат
0 1 5 6 7 8 9 11 50
⇑
Связанные темы
- Алгоритмы работы с данными которые представлены по принципу «кучи» (heap). Алгоритмы make_heap, push_heap, pop_heap, sort_heap
- Алгоритмы определения минимума и максимума. Алгоритмы min, min_element, max, max_element, lexicographical_compare
- Алгоритмы перестановок. Алгоритмы next_permutation, prev_permutation
- Немодифицирующие алгоритмы. Поиск. Алгоритмы find, find_if, find_first_of, find_end, adjanced_find, search, search_n
- Немодифицирующие алгоритмы. Алгоритмы count, count_if, equal, equal_range, mismatch
⇑