При написании обобщенного программного кода следует, по мере возможности, пытаться пользоваться наиболее общим типом итератора. Это подразумевает, что, когда возможно, вы должны стараться писать обобщенные алгоритмы с единственным проходом по потоку ввода. При таком подходе ваш обобщенный программный код не ограничивается только контейнерами, а может также использоваться с такими итераторами ввода, как
istream_iterator
. Кроме того, алгоритмы с единственным проходом часто более эффективны.
Возможно,
вас удивляет то, что я решил тип, возвращаемый функцией
computeMean
из примера 11.7, передать в качестве параметра шаблона, а не выводить его из типа итератора. Это сделано по той причине, что обычно статистические расчеты выполняются с более высокой точностью, чем точность значений, содержащихся в контейнере. Так, в программном коде примера 11.7 возвращаемое среднее значение набора чисел целого типа имеет тип
double
.
11.4. Фильтрация значений, выпадающих из заданного диапазона
Проблема
Требуется проигнорировать содержащиеся в последовательности значения, которые располагаются ниже или выше заданного диапазона.
Решение
Используйте функцию
remove_copy_if
, определенную в
<algorithm>
, как показано в примере 11.8.
Пример 11.8 Удаление из последовательности элементов, значения которых меньше заданного
Программа примера 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
из заголовочного файла
<numeric>
можно использовать для расчета многих статистических параметров, а не только для суммирования пользовательских объектов-функций. Пример 11.9 показывает, как можно вычислить значения некоторых важных статистические функций при помощи