Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
STL5 / lab6-algorithms / lab6-algorithms.doc
Скачиваний:
8
Добавлен:
10.04.2015
Размер:
203.26 Кб
Скачать

Удалить (Remove)

template <class ForwardIterator, class T>

ForwardIterator remove(ForwardIterator first, ForwardIterator last,

const T& value);

template <class ForwardIterator, class Predicate>

ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,

Predicate pred);

remove– удаляет из последовательности [first;last) элементы равные заданному (для сравнения используетсяoperator==) или те, для которых предикатpredвозвратит значениеtrue.removeустойчив, то есть относительный порядок элементов, которые не удалены, такой же, как их относительный порядок в первоначальном диапазоне.

Необходимо понимать, поскольку алгоритм использует для доступа к последовательности итераторы и не имеет информации в каком контейнере они находятся, он не может реально удалить элементы из контейнера (код алгоритм даже не имеет ссылки на контейнер, элементы которого он обрабатывает). Поэтому алгоритмы, которые должны удалять элементы из последовательности, реально просто переносят те элементы, которые не должны быть удаленыв начало последовательности, и возвращают итератор указывающий на элементследующих на последним неудаленным элементом. Элементы начиная с этого итератора и до конца последовательности считаются удаленными и могут содержать произвольные значения.

Следующие пример демонстрирует работу алгоритма 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 removed_range;

removed_range = remove_if(v1.begin(),v1.end(),isEven);

for_each(v1.begin(),v1.end(),print_elem);

cout << endl;

for_each(removed_range,v1.end(),print_elem);

cout << endl;

return 0;

}

Вывод программы:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // исходная последовательность

1, 3, 5, 7, 9, 6, 7, 8, 9, 10, // послед. после удаления четных элементов

6, 7, 8, 9, 10, // то, что находится на месте удаленных

// элементов в данном случае, старые значения

Для того, чтобы реально удалить элементы из контейнера применяется так называемая идиома erase-remove, когда алгоритм remove переносит «нужные» элементы в начало, а метод контейнера erase удаляет «ненужные» используя итератор возвращенный алгоритмом remove.

Для того, чтобы реально удалить элементы из контейнера необходимо добавить строку

v1.erase(removed_range,v1.end());

Более коротко идиома erase-remove для приведенного примера может быть записана следующим образом

v1.erase(remove_if(v1.begin(),v1.end(),isEven),v1.end());

template <class InputIterator, class OutputIterator, class T>

OutputIterator remove_copy(InputIterator first, InputIterator last,

OutputIterator result, const T& value);

template <class InputIterator, class OutputIterator, class Predicate>

OutputIterator remove_copy_if(InputIterator first, InputIterator last,

OutputIterator result, Predicate pred);

remove_copy– копирует из последовательности [first;last) все элементы не равныеvalue(для сравнения используетсяoperator==) или те, для которых предикатpredвозвратил значениеfalse.remove_copyустойчив, то есть относительный порядок элементов в результирующем диапазоне такой же, как их относительный порядок в первоначальном диапазоне. Алгоритм возвращает итератор, указывающий на элемент следующий за последним выведенным элементом.

Соседние файлы в папке lab6-algorithms