C++. Сборник рецептов - [149]

Шрифт
Интервал


>int main() {

> vector v;

> v.push_back(0);

> v.push_back(1);

> v.push_back(2);

> cout << v.size() << endl;

> cout << distance(v.begin(), v.end()) << endl;

>}

Программа примера 11.1 выдает следующий результат.

>3

>3

Обсуждение

Функция-член >size, которая возвращает количество элементов стандартного контейнера, является наилучшим решением в тех случаях, когда доступен объект контейнера. В примере 11.1 я также продемонстрировал применение функции >distance, потому что при написании обобщенного программного кода обычно имеешь дело только с парой итераторов. Работая с итераторами, вы часто не знаете тип контейнера и не имеете доступа к его функциям-членам.

Функция >distance, как и большинство алгоритмов STL, в действительности является шаблонной функцией. Поскольку тип аргумента шаблона может автоматически выводиться компилятором по аргументам функции, вам не надо его передавать как параметр шаблона. Конечно, при желании можно явно указать тип параметра шаблона, как это сделано ниже.

>cout << distance::iterator>(v.begin(), v.end()) << endl;

Производительность функции >distance зависит от типа используемого итератора. Время ее выполнения будет постоянным, если итератор ввода является итератором с произвольным доступом; в противном случае время ее работы будет линейным. (Концепция итератора рассматривается в рецепте 7.1.)

Смотри также

Рецепт 15.1.

11.2. Поиск наибольшего или наименьшего значения в контейнере

Проблема

Требуется найти максимальное или минимальное значение в контейнере.

Решение

Пример 11.2 показывает, как можно находить максимальные и минимальные элементы контейнера с помощью функций >max_element и >min_element, определенных в заголовочном файле >. Эти функции возвращают итераторы,. которые ссылаются на первый элемент, имеющий самое большое или самое маленькое значение соответственно.

Пример 11.2. Поиск минимального или максимального элемента контейнера

>#include

>#include

>#include


>using namespace std;


>int getMaxInt(vector& v) {

> return *max_element(v.begin(), v.end());

>}


>int getMinInt(vector& v) {

> return *min_element(v.begin(), v.end());

>}


>int main() {

> vector v;

> for (int i=10; i < 20; ++i) v.push_back(i);

> cout << "min integer = " << getMinInt(v) << endl;

> cout << "max integer = " << getMaxInt(v) << endl;

>}

Программа примера 11.2 выдает следующий результат.

>min integer = 10

>max integer =19

Обсуждение

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

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

Пример 11.3. Обобщенная функция, возвращающая минимальное и максимальное значения

>#include

>#include

>#include


>using namespace std;


>template

>void computeMinAndMax(Iter_T first, Iter_T last, Value_T& min, Value_T& max) {

> min = *min_element(first, last);

> max = *max_element(first, last);

>}


>int main() {

> vector v;

> for (int i=10; i < 20; ++i) v.push_back(i);

> int min = -1;

> int max = -1;

> computeMinAndMax(v.begin(), v.end(), min, max);

> cout << "min integer = " << min << endl;

> cout << "max integer = " << max << endl;

>}

В примере 11.3 я написал шаблон функции >computeMinAndMax, которая принимает два параметра шаблона: один — это тип итератора, другой — тип минимальных и максимальных значений. Поскольку оба параметра шаблона являются также параметрами функции, компилятор C++ может догадаться, какие два отдельных типа (>Iter_T и >Value_T) используются, как это я продемонстрировал в рецепте 11.1. Это позволяет мне не указывать явно тип параметров шаблона, как это сделано ниже.

>compute_min_max::iterator, int>(...)

При выполнении функций >min_element и >max_element используется оператор >operator< для сравнения значений, на которые ссылаются итераторы. Это значит, что, если итератор ссылается на тип, который не поддерживает этот тип сравнения, компилятор выдаст сообщение об ошибке. Однако функции >min_element и >max_element можно также использовать с функтором сравнения, определенным пользователем, т.е. с указателем на функцию или с объектом-функцией.

Для функций >min_element и >max_element необходим специальный функтор, принимающий два значения (они имеют тип объектов, на которые ссылается итератор) и возвращающий значение типа


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».В книге подробно рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.