1.13. Использование функций remove и remove_if

В этом разделе мы рассмотрим три алгоритма, используя их для векторов, но имея в виду, что они также применимы к двусторонним очередям и спискам.

Алгоритм findjf

В дополнение к алгоритму find, использовавшемуся в разделе 1.5 для на­хождения элементов вектора с заданным значением, имеется также алго­ритм find_if, который является более общим в том смысле, что в качестве одного из аргументов принимает предикат (см. раздел 1.11). Этот алгоритм ищет в векторе первый элемент, который удовлетворяет условию, указан­ному в этом предикате. Например, следующая программа ищет в векторе первый элемент */, удовлетворяющий

3 < *i < 8

Эта программа проверяет, найден ли такой элемент, и в этом случае печа­тает его значение:

// find_if.срр:  Демонстрация алгоритма find_if. #include <iostream> #include <vector> #include <algorithm> using namespace  std;

bool  condition(int x)

{    return  3  <= x && x <=  8;

}

int main()

{    vector<int> v;

v.push_back(10);   v.push_back(7); v.push_back(4);   v.push_back(1); vector<int>::iterator  i;

i  =  find_if(v.begin(),   v.endf),   condition); if   (i   != v.endf))

cout  <<   "Found element:   "   «  *i  << endl; return 0; }

Как легко предугадать, вывод программы будет следующий:

Found element:   7

поскольку в последовательности {10, 7, 4, 1} значение 7 первое находится в диапазоне между 3 и 8. Программа также будет правильно работать, если заменить функцию функциональным объектом (см. раздел 1.12). Для этого вместо функции condition напишем следующее определение класса:

class CondObject { public:

bool operator()(int x)

{ return 3 <= x && x <= 8;

} };

В то же время мы заменим вызов find_if в тексте программы на следующий:

i  =  find_if(v.beginf),  v.endf),   CondObject());

Алгоритмы remove и removeif

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

1. Переупорядочить вектор с помощью вызова remove, разместив все эле­менты, которые мы хотим оставить, в начале вектора. Эта операция стабильна: порядок, в котором будут находиться сохраненные элемен­ты, не изменится.


<< назад вперед >>