|
Программирование >> Немодифицирующие последовательные алгоритмы
выглядит довольно необычно. Первая часть этой записи, 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.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |