Выбрать главу

// Демонстрация использования алгоритма reverse.

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

int main()

{

 vector<int> v;

 unsigned int i;

 for(i=0; i<10; i++) v.push_back(i);

 cout << "Исходная последовательность: ";

 for(i=0; i<v.size(); i++)

  cout << v[i] << " ";

 cout << endl;

 reverse (v.begin(), v.end());

 cout << "Реверсированная последовательность: ";

 for(i=0; i<v.size(); i++) cout << v[i] << " ";

 return 0;

}

Результаты выполнения этой программы таковы.

Исходная последовательность: 0123456789

Реверсированная последовательность: 9876543210

Преобразование последовательности

Одним из самых интересных алгоритмов является transform(), поскольку он позволяет модифицировать каждый элемент в диапазоне в соответствии с заданной функцией. Алгоритм transform() используется в двух общих форматах.

template <class InIter, class OutIter, class Func>

OutIter transform(InIter start, InIter end, OutIter result, Func unaryfunc);

template <class InIter1, class InIter2, class OutIter, class Func>

OutIter transform(InIter1 start1, InIter1 end1, InIter2 start2, OutIter result, Func binaryfunc);

Алгоритм transform() применяет функцию к диапазону элементов и сохраняет результат в последовательности, заданной параметром result. В первой форме диапазон задается параметрами start и end. Применяемая для преобразования функция задается параметром unaryfunc. Она принимает значение элемента в качестве параметра и должна возвратить преобразованное значение. Во второй форме алгоритма преобразование выполняется с использованием бинарной функции, которая принимает в качестве первого параметра значение предназначенного для преобразования элемента из последовательности, а в качестве второго параметра — элемент из второй последовательности. Обе версии возвращают итератор, указывающий на конец результирующей последовательности.

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

// Пример использования алгоритма transform.

#include <iostream>

#include <list>

#include <algorithm>

using namespace std;

// Простая функция преобразования.

int xform(int i) {

 return i * i; // квадрат исходного значения

}

int main()

{

 list<int> x1;

 int i;

 // Помещаем значения в список.

 for(i=0; i<10; i++) x1.push_back(i);

 cout << "Исходный список x1: ";

 list<int>:: iterator p = x1.begin();

 while(p != x1.end()) {

  cout << *p << " ";

  p++;

 }

 cout << endl;

 // Преобразование списка x1.

 p = transform(x1.begin(), x1.end(), x1.begin(), xform);

 cout << "Преобразованный список x1: ";

 p = x1.begin();

 while(p != x1.end()) {

  cout << *p << " ";

  p++;

 }

 return 0;

}

При выполнении эта программа генерирует такие результаты.

Исходный список x1: 0 1 2 3 4 5 6 7 8 9

Преобразованный список x1: 0 1 4 9 16 25 36 49 64 81

Как видите, каждый элемент в списке x1 теперь возведен в квадрат.

Исследование алгоритмов

Описанные выше алгоритмы представляют собой только малую часть всего содержимого библиотеки STL. И конечно же, вам стоит самим исследовать другие алгоритмы. Заслуживают внимания многие, например set_union() и set_difference(). Они предназначены для обработки содержимого такого контейнера, как множество. Интересны также алгоритмы next_permutation() и prev_permutation(). Они создают следующую и предыдущую перестановки элементов заданной последовательности. Время, затраченное на изучение алгоритмов библиотеки STL, — это время, потраченное не зря!