Программирование >>  Немодифицирующие последовательные алгоритмы 

1 ... 10 11 12 [ 13 ] 14 15 16 ... 78


выглядит довольно необычно. Первая часть этой записи, compareQ, представляет собой вызов конструктора по умолчанию класса compare. Другими словами, выражение compareQ представляет объект типа compare, и за ним, как и у г), может следовать список аргументов, в этом примере (5, 3).

Следующая программа, основывающаяся на использовании функционального объекта, эквивалентна программе dsorti из предьщущего раздела:

dsort2 .срр: Сортировка в нисходящем порядке

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

функционального объекта.

#include <iostream>

#include <algorithin>

using namespace std;

class compare {

public:

bool operator()(int x, int у)const

{ return x > y;

int mainO { const int N = 8; int a[N] =

{1234, 5432, 8943, 3346, 9831, 7842, 8863, 9820}; cout Before sorting:\n ;

copy(a, a+N, ostream iterator<int>(cout, ));

cout endl;

sort (a, a+N, compared);

cout After sorting in descending order:\n ; copy(a, a+N, ostream iterator<int>(cout, )); cout endl; return 0;

В действительности нет необходимости определять класс compare, поскольку в STL уже есть подобное определение в более общей форме шаблона. Следовательно, мы можем опустить класс compare и при вызове алгоритма sort заменить compare) на greater<int>Q. Это дает нам следующую, окончательную версию:

dsort3 .срр: Сортировка в нисходящем порядке

с использованием шаблона greater.

#include <iostream>

#include <algorithm>

#include <functional>

using namespace std;



int main() { const int N = 8; int a[N] =

{1234, 5432, 8943, 3346, 9831, 7842, 8863, 9820}; cout << Before sorting:\n ;

copy(a, a+N, ostream iterator<int>(cout, )); cout endl;

sort(a, a+N, greater<int>());

cout << After sorting in descending order:\n ; copy(a, a+N, ostream iterator<int>(cout, )); cout endl; return 0;

Обсудим функциональные объекты более подробно в главе 6.

1.13. Использование findif, remove и remove if

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

Алгоритм findjf

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

3 < *г < 8

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

find if.cpp: Демонстрация алгоритма 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(l); vector<int>::iterator i;

i = find if(v.begin(), v.end(), condition); if (i != V.endO )

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;

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

i = find if (v.beginO , v.endO, CondObject ()) ; Алгоритмы remove и removeif

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

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

2. Стереть те элементы, которые нам не нужны; теперь они расположены в конце вектора.

Алгоритм remove возвращает новый логический конец данных, не изменяя размер контейнера. Мы можем стереть мусор , начиная с возвращенного конца с помощью функции-члена erase, рассмотренной в конце раздела 1.3.



1 ... 10 11 12 [ 13 ] 14 15 16 ... 78

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика