- •Алгоритмы немодифицирующие последовательность Операции с каждым элементом (For each)
- •Поиск (Find)
- •Найти повторение (Аdjacent find)
- •Подсчет (Count)
- •Сравнение на равенство (Equal)
- •Отличие (Mismatch)
- •Поиск подпоследовательности (Search)
- •Алгоритмы модифицирующие последовательность Копировать (Copy)
- •Обменять (Swap)
- •Преобразовать (Transform)
- •Заменить (Replace)
- •Заполнить (Fill)
- •Породить (Generate)
- •Удалить (Remove)
- •Разделить (Partitions)
- •Убрать повторы (Unique)
- •Расположить в обратном порядке (Reverse)
Разделить (Partitions)
template <class BidirectionalIterator, class Predicate>
BidirectionalIterator partition(BidirectionalIterator first,
BidirectionalIterator last, Predicate pred);
partition– разделяет элементы последовательности на две группы, в начале последовательности содержатся элементы, для которых предикатpredвозвратилtrue, в конце элементы, для которых предикатpredвозвратилfalse. Алгоритм возвращает итератор, указывающий на начало второй группы элементов. Алгоритм в чем-то похож на алгоритмremove, отличие в том, чтоpartitionразделяет последовательность на две группы, аremoveвыделяет одну группу, при этом вторая содержит неопределенные значения (или старые значения).
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
void print_elem(int val)
{
cout << val << ", ";
}
bool isEven(int arg)
{
return (arg % 2) == 0;
}
int main()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
v1.push_back(6);
v1.push_back(7);
v1.push_back(8);
v1.push_back(9);
v1.push_back(10);
for_each(v1.begin(),v1.end(),print_elem);
cout << endl;
vector<int>::iterator iter;
iter = partition(v1.begin(),v1.end(),isEven);
for_each(v1.begin(),v1.end(),print_elem);
cout << endl;
for_each(iter,v1.end(),print_elem);
cout << endl;
return 0;
}
Вывод программы:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
10, 2, 8, 4, 6, 5, 7, 3, 9, 1,
5, 7, 3, 9, 1,
Отметим, что относительный порядок элементов изменился, т.е. порядок элементов в каждой группе отличается от порядка этих же элементов до разделения. Относительный порядок элементов сохраняется при использовании алгоритма stable_partition
template <class BidirectionalIterator, class Predicate>
BidirectionalIterator stable_partition(BidirectionalIterator first,
BidirectionalIterator last, Predicate pred);
Вывод предыдущего примера в случае использования stable_partitionбудет иметь вид:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2, 4, 6, 8, 10, 1, 3, 5, 7, 9,
1, 3, 5, 7, 9,
Однако использование stable_partitionпо сравнению сpartitionтребует дополнительных накладных расходов, менее эффективно. Использоватьstable_partitionимеет смысл только в случае если действительно необходимо сохранить относительный порядок элементов.
Убрать повторы (Unique)
template <class ForwardIterator>
ForwardIterator unique(ForwardIterator first, ForwardIterator last);
template <class ForwardIterator, class BinaryPredicate>
ForwardIterator unique(ForwardIterator first, ForwardIterator last,
BinaryPredicate binary_pred);
unique– удаляет все, кроме первого, элементы из каждой последовательной группыравных элементов, в последовательности [first;last). Для сравнения элементов используется либоoperator==, либо двоичный предикатbinary_pred. Отметим, что повторяющиеся элементы удаляются из групп соседних элементов, т.е. чтобы удалить повторяющиеся элементы из всей последовательности ее необходимо сначала отсортировать. Как и алгоритмremoveалгоритмuniqueреально не удаляет данные из последовательности, а переносит неудаленные элементы в начало, и возвращает итератор, указывающий на начало последовательности удаленных элементов, для полного удаления элементов из контейнер должна быть применена идиомаerase-remove.
Пример работы алгоритма unique:
#include "stdafx.h"
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
void print_elem(int val)
{
cout << val << ", ";
}
int main()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(1);
v1.push_back(1);
v1.push_back(3);
v1.push_back(1);
v1.push_back(4);
v1.push_back(1);
v1.push_back(1);
v1.push_back(5);
for_each(v1.begin(),v1.end(),print_elem);
cout << endl;
v1.erase(unique(v1.begin(),v1.end()),v1.end());
for_each(v1.begin(),v1.end(),print_elem);
cout << endl;
sort(v1.begin(),v1.end());
v1.erase(unique(v1.begin(),v1.end()),v1.end());
for_each(v1.begin(),v1.end(),print_elem);
cout << endl;
return 0;
}
Вывод программы
1, 2, 1, 1, 3, 1, 4, 1, 1, 5
1, 2, 1, 3, 1, 4, 1, 5,
1, 2, 3, 4, 5,
template <class InputIterator, class OutputIterator>
OutputIterator unique_copy(InputIterator first, InputIterator last,
OutputIterator result);
template <class InputIterator, class OutputIterator,
class BinaryPredicate>
OutputIterator unique_copy(InputIterator first, InputIterator last,
OutputIterator result, BinaryPredicate binary_pred);
unique_copy– алгоритм аналогичныйunique, за исключение того, что он не переносит неудаляемые элементы в начало последовательности, а копирует их в последовательность заданную итераторомresult