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

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

и >ostream_iterator является хорошей привычкой, так как с их помощью легче создавать повторно используемый программный код

Итератор >istream_iterator позволяет выполнить только один проход по данным, поэтому вы можете вызвать либо >accumulate, либо >distance, но если вы вызываете обе функции, данные становятся недействительными, и всякая последующая попытка их просмотра, вероятно, приведет к неудаче. Пример 11.7 показывает, как можно написать более обобщенную функцию по расчету среднего значения за один проход последовательности чисел.

Пример 11.7. Более обобщенная функция по расчету среднего значения

>#include

>#include

>#include


>using namespace std;


>template

>Value_T computeMean(Iter_T first, Iter_T last) {

> if (first == last) throw domain_error("mean is undefined");

> Value_T sum;

> int cnt = 0;

> while (first != last) {

>  sum += *first++;

>  ++cnt;

> }

> return sum / cnt;

>)


>int main() {

> cout << "please type in several integers separated by newlines" << endl;

> cout << "and terminated by an EOF character (i.e , Ctrl-Z)" << endl;

> double mean = computeMean(

>  istream_iterator(cin), istream_iterator());

> cout << "the mean is " << mean << endl;

>}

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

Возможно, вас удивляет то, что я решил тип, возвращаемый функцией >computeMean из примера 11.7, передать в качестве параметра шаблона, а не выводить его из типа итератора. Это сделано по той причине, что обычно статистические расчеты выполняются с более высокой точностью, чем точность значений, содержащихся в контейнере. Так, в программном коде примера 11.7 возвращаемое среднее значение набора чисел целого типа имеет тип >double.

11.4. Фильтрация значений, выпадающих из заданного диапазона

Проблема

Требуется проигнорировать содержащиеся в последовательности значения, которые располагаются ниже или выше заданного диапазона.

Решение

Используйте функцию >remove_copy_if, определенную в >, как показано в примере 11.8.

Пример 11.8 Удаление из последовательности элементов, значения которых меньше заданного

>#include

>#include

>#include

>#include


>using namespace std;


>struct OutOfRange {

> OutOfRange(int min, int max) :

>  min_(min), max_(max) {}


> bool operator()(int x) {

>  return (x < min_) || (x > max_);

> }

> int min_;

> int max_;

>};


>int main() {

> vector v;

> v.push_back(6);

> v.push_back(12);

> v.push_back(10);

> v.push_back(24);

> v.push_back(30);

> remove_copy_if(v.begin(), v.end(),

> ostream_iterator(cout, "\n"), OutOfRange(10, 25));

>}

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

>12

>18

>24

Обсуждение

Функция >remove_copy_if копирует элементы из одного контейнера в другой контейнер (или итератор вывода), игнорируя те элементы, которые удовлетворяют предоставленному вами предикату (вероятно, было бы более правильно назвать функцию >copy_ignore_if). Однако эта функция не изменяет размер целевого контейнера. Если (как часто бывает) количество скопированных функцией >remove_copy_if элементов меньше, чем размер целевого контейнера, вам придется уменьшить целевой контейнер с помощью функции-члена >erase.

Для функции >remove_copy_if требуется унарный предикат (функтор, который принимает один аргумент и возвращает значение типа >boolean), который возвращает значение «истина», когда элемент не должен копироваться. В примере 11.8 предикатом является объект-функция >OutOfRange. Конструктор >OutOfRange принимает нижнюю и верхнюю границу и перегружает оператор >operator(). Функция >operator() принимает параметр целого типа и возвращает значение «истина», если переданный аргумент меньше, чем нижняя граница, или больше, чем верхняя граница.

11.5. Вычисление дисперсии, стандартного отклонения и других статистических функций

Проблема

Требуется рассчитать значение одной или нескольких обычных статистических функций, например дисперсии (variance), стандартного отклонения (standard deviation), коэффициента асимметрии (skew) и эксцесса (kurtosis) для последовательности чисел.

Решение

Функцию >accumulate из заголовочного файла > можно использовать для расчета многих статистических параметров, а не только для суммирования пользовательских объектов-функций. Пример 11.9 показывает, как можно вычислить значения некоторых важных статистические функций при помощи >accumulate.

Пример 11.9. Статистические функции

>#include

>#include

>#include

>#include

>#include

>#include


>using namespace std;


>template

>T nthPnwer(T x) {

> T ret = x;

> for (int i=1; i < N; ++i) {

>  ret *= x;

> }

> return ret;

>}


>template

>struct SumDiffNthPower {


Рекомендуем почитать
Изучаем 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-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.