|
Программирование >> Немодифицирующие последовательные алгоритмы
not2own.cpp: Использование адаптера not2 с нашим собственным функциональным объектом, ttinclude <iostream> iinclude <algorithm> iinclude <functional> using namespace std; struct iLessThan: binary function<int, int, bool> { bool operator!)(int x, int у)const {return x < y;} }; int mainO { int a[5] = {50, 30, 10, 40, 20}; sort(a, a+5, not2(iLessThan())); for (int i=0; i<5; i++) cout a[i] ; Вывод: 50 40 30 20 10 cout endl; return 0; Адаптер notl также можно использовать с нашим функциональным объектом. В предыдущем разделе был использован notl в выражении notl(bind2nd(less<int>(), 100)) из программы notldemo.cpp, чтобы сосчитать, сколько элементов массива не меньше 100. В этом выражении мы заменим bind2nd(less<int>(), 100) более простой формой LessThanlOO() где LessThanlOO - определенный нами класс, как показано в следующей программе: notlown.cpp: Использование адаптера notl с нашим собственным функциональным объектом. iinclude <iostream> iinclude <algorithm> iinclude <functional> using namespace std; struct LessThanlOO: unary function<int, bool> { bool operator()(int x)const {return x < 100;} }; int mainO { int a[10] = {800, 3, 4, 600, 5, 6, 800, 71, 100, 2}, n = 0; Подсчитаем количество элементов, не меньших 100: п = count if(a, а+10, notl(LessThanlOO())) ; cout n endl; Вывод: 4 return 0; В этой программе фрагмент : unary function<int, bool> определяет базовый класс, наследником которого является класс LessThanlOO. Мы пишем unary Junction<int, bool>, потому что адаптер notl работает с унарным предикатом, который принимает в качестве параметра целое значение и возвращает значение типа bool. Напомним, что определение класса unary Junction было приведено в разделе 6.1. 6.5. Функциональные объекты и алгоритм transform Как видно из раздела 2.4, STL определяет следующие шаблонные классы, которые мы можем использовать как функциональные объекты, сопроводив их парой скобок: plus<T> minus<T> multiplies<T> divides<T> modulus<T> equal to<T> not equal to<T> greater<T> less<T> greater equal<T> less equal<T> logical and<T> logical or<T> llegate<T> logical not<T> Чтобы проиллюстрировать работу некоторых функциональных объектов этого списка (не рассмотренных ранее), для начала обсудим алгоритмы transform. Этих алгоритмов в STL два - для унарной и для бинарной операций. Они нужны для преобразования всех элементов в диапазоне. Предположим, например, что нам требуется использовать элементы a[i] целочисленного массива а для присваивания значений b[i] = -a[i] другому массиву Ь. Один из способов достичь этого состоит в применении алгоритма transform для унарной операции совместно с шаблоном negate<T>, как показывает следующая программа: negate.срр: Алгоритм transform и negate<T>. ♦include <iostream> ♦include <algorithm> ♦include <functional> using namespace std; int main О { int а[5] = {10, 20, -18, 40, 50}, b[5]; transform(a, а + 5, b, negate<int>()); for (int i=0; i<5; i++) cout b[i] Вывод: -10 -20 18 -40 -50 cout endl; return 0; Функциональный объект logical not<T>{) очень похож на negate<T>{). Если мы напишем transform(а, а + 5, b, logical not<int>()); массиву b будут присвоены значения b{i\ = ! a{i\. Напомним, что мы можем вместо bool, true и false писать int, 1 и 0. А в качестве источника и приемника допустимо использовать одий и тот же массив. Например, вызов transform(а, а + 5, а, negate<int>()); будет равнозначен умножению пяти элементов массива а на -1. Перейдем теперь к знакомству с бинарной версией алгоритма transform. Этот вариант использует два контейнера-источника вместо одного, а также бинарный функциональный объект. Для примера предположим, что мы хотим использовать массивы аиЬ для вычисления следующей суммы в массиве 5: 5[i] = аЩ + b\i] Следующая программа показывает, как этого можно достичь с помощью шаблона plus<int>: II plus.срр: Алгоритм transform и plus<T>. iinclude <iostream> iinclude <algorithm> iinclude <functional> using namespace std; int mainO { int a[5] = {10, 20, -18, 40, 50}, b[5] = { 2, 2, 5, 3, 1}, s[5]; transform(a, a + 5, b, s, plus<int>()); for (int i=0; i<5; i++) cout s[i] ; Вывод: 12 22 -13 43 51 cout endl; return 0; Если необходимо, можно вместо отдельного массива s при вызове transform использовать один из источников а или Ь.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |