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

1 ... 44 45 46 [ 47 ] 48 49 50 ... 78


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 использовать один из источников а или Ь.



1 ... 44 45 46 [ 47 ] 48 49 50 ... 78

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