Алгоритмы count_if и find_if

Алгоритмы count и find

Использование алгоритмов

2500 400 17 5 1

P.pop();

P.push(2500); P.push(1);

P.push(17); P.push(5); P.push(400);

while (!P.empty()) {

cout << P.front() << ' ';

}

return 0;

}

 

Результат выполнения программы:

 

Вернемся к изучению алгоритмов. Не забывайте включать заголовочный файл <algor1thm> и добавлять определение нашей функции print (), если она используется.

 

Алгоритм count подсчитывает количество вхождений в контейнер (или его часть) значения, заданного его третьим аргументом.

Алгоритм find выполняет поиск заданного значения и возвращает итератор на самое первое вхождение этого значения.

Если значение не найдено, то возвращается итератор, соответствующий возврату метода end(). В следующей программе показано использование этих алгоритмов.

int main() {

int arr[ ] = {1, 2, 3, 4, 5, 2, 6, 2, 7};

int n = sizeof(arr) / sizeof(int);

vector<int> v1(arr, arr + n);

int value = 2 ; // искомая величина

int how_much = count (vl.begin(), vl.end(), value);

cout << how_much << endl; // вывод: 3

list<int> loc_list; // список позиций искомой величины

vector<int>: :iterator location = v1.begin();

while (1) {

location = find (location, v1.end(), value);

if (location == v1.end()) break;

loc_list.push_back(location – v1.begin());

location++;

}

print(loc_list); // вывод: 1 5 7

return 0;

}

В приведенной программе создается вектор v1, наполняясь при инициализации значениями из массива arr.

Затем с помощью алгоритма count подсчитывается количество вхождений в вектор значения value, равного двум.

В цикле while выясняется, на каких позициях в векторе размещена эта величина.

Обратите внимание на то, что первый аргумент алгоритма find (переменная location) первоначально — перед входом в цикл — принимает значение итератора, указывающего на нулевой элемент контейнера.

Затем location получает значение итератора, указывающего на найденный элемент.

Если поиск завершился успешно, то, во-первых, вычисляется позиция найденного элемента как разность значений location и адреса нулевого элемента.

Полученное значение заносится в список loc_list .

Во-вторых, итератор location сдвигается операцией инкремента па следующую позицию в контейнере, чтобы обеспечить (на следующей итерации цикла) продолжение поиска в оставшейся части контейнера.

Если поиск завершился неудачей, то break приведет к выходу

из цикла.

Алгоритмы count_if и find_if отличаются от алгоритмов count и find тем, что в качестве третьего аргумента они требуют некоторый предикат.

Предикат — это функция, возвращающая значение типа bool.

Например, если в предыдущей программе добавить определение глобальной функции:

 

bool isMyValue (int х) { return ((х > 2) && (х < 5)); }

 

и заменить инструкцию с вызовом count на:

 

int how_much = count_if (v1.begin(), v1.endO, isMyValue);

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

 

Аналогично, замена инструкции с вызовом find на

 

location = find_if (location, v1.end() , isMyValue);

будет иметь следствием наполнение списка loc_list двумя значениями: 2 и 3 (номера позиций вектора v1, на которых находятся числа, удовлетворяющие предикату isMyValue).