Программирование >>  Операторы преобразования типа 

1 ... 31 32 33 [ 34 ] 35 36 37 ... 239


int mainO

vector<str1ng> coll:

/* Загрузка слов из стандартного входного потока данных

* - источник: все строки до конца файла Сипи до возникновения ошибки)

* - приемник: coll (вставка) */

сору Cistrea[n iterator<string>(cin). Начало источника istream iterator<string>(). Конец источника

back inserter(coll)): Приемник

Сортировка элементов

sort (coll.beginO. coll.endO);

Вывод всех элементов без дубликатов

* - источник: соИ

* - приемник: стандартный вывод (с разделением элементов

* символом новой строки) */

unique copy (coll.beginO. coll.endO. Источник

ostream iterator<string>(cout. \n )); Приемник

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

сору (istrea(Ti iterator<string>(cin). 1stream iterator<string>(). back 1nserter(coll)):

О Выражение istream iterator<string>(cin) создает потоковый итератор для чтения из стандартного входного потока данных cin. Аргумент string определяет тип элементов, читаемых потоковым итератором (строковые типы рассматриваются в главе 11). Элементы читаются стандартным оператором ввода >>. Каждый раз, когда алгоритм пытается обработать следующий элемент, потоковый итератор ввода преобразует эту попытку в вызов:

cin строка

Оператор чтения строк обычно читает отдельное слово , отделенное пропуском от следующего слова (см. с. 475), поэтому алгоритм вводит данные по словам.

О Выражение istream iterator<string>() вызывает конструктор по умолчанию и создает конечный потоковый итератор. Он представляет поток данных, дальнейшее чтение из которого невозможно.

В старых системах ио втором параметре шаблона должен присутствовать тип ptrdiff t (см. с. 281).



Как обычно, алгоритм сору() продолжает работать до тех пор, пока первый (наращиваемый) аргумент не сравняется со вторым аргументом. Конечный потоковый итератор определяет конец обрабатываемого интервала; следовательно, алгоритм будет читать все строки из cin до тех пор, пока дальнейшее чтение станет невозможным (из-за достижения конца потока данных нли из-за ошибки).

Подведем итог: источником данных для алгоритма сору() являются все слова из cin*-. Прочитанные слова копируются в соН конечным итератором вставки.

Алгоритм sort() сортирует все содержимое коллекции:

sort Ccoll .beginO. coll.endO):

Наконец, следующая команда копирует все элементы коллекции в приемник cout;

unique copy Ccoll.beginO. coll.endO.

ostreafn iteratQr<string>(CQut. \n ));

В процессе копирования алгоритм unique copy исключает из копируемых данных дубликаты. Представленное ниже выражение создает потоковый итератор вывода, который записывает string в выходной поток данных cout, вызывая оператор << для каждого элемента:

ostream iterator<string>Ccout. Лп )):

Второй аргумент определяет разделитель, выводимый между элементами. Передавать этот аргумент не обязательно. В нашем примере разделителем является символ новой строки, поэтому каждый элемент будет выводиться в отдельной строке.

Все компоненты программы реализованы в виде шаблонов, поэтому программа легко адаптируется для сортировки других типов данных (например, целых чисел или более сложных объектов). На с. 281 эта тема рассматривается более подробно и поясняется дополнительными примерами использования потоковых итераторов ввода-вывода.

В нашем примере для сортировки всех слов в стандартном входном потоке данных понадобились одно объявление и три команды. Однако аналогичного результата можно добиться всего одним объявлением и одной командой. Пример приведен на с. 232.

Обратные итераторы

Третей разновидностью нтераторных адаптеров STL являются обратные итераторы. Эти итераторы работают в противоположном направлении: вызов оператора -и- на внутреннем уровне преобразуется в вызов оператора --, и наоборот. Все контейнеры поддерживают создание обратных итераторов функциями rbeginO и rend(). Рассмотрим следующий пример:

stl/riterl.cpp #include <iastream> #include <vector> Iinclude <algorith[n>



Модифицирующие алгоритмы 121

using namespace std;

1nt mainO {

vector<int> col 1:

Вставка элементов со значениями от 1 до 9 for (int i=l: i<=9: ++i) { coll,push back(i);

Вывод всех элементов в обратном порядке сору (coll .rbeginO . coll.rendO. Источник

ostream 1terator<int>(cout. )); Приемник cout endl;

Выражение coll.rbegin() возвращает обратный итератор для коллекции coll. Полученный итератор может иснользоваты:я, чтобы начать обратный перебор элементов коллекции, поскольку он устанавливается на последний элемент коллекции. Таким образом, выражение *coll.rbegin() возвращает значение последнего элемента.

Соответственно выражение coll.rend() возвращает обратный итератор для коллекции соП, который может использоваться для завершения перебора в обратном направлении. По аналогии с обычными интервалами он устанавливается за концом интервала, но в противоположном направлении - то есть перед первым элементом коллекции.

Значение выражения *coll.rend() не определено, как, впрочем, и значение *coll.end(). Никогда не используйте операторы * и -> с позициями, не представляющими реальных элементов коллекции.

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

9 8 7 6 5 4 3 2 1

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

Модифицирующие алгоритмы

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



1 ... 31 32 33 [ 34 ] 35 36 37 ... 239

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