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<int>(cout, ' '), 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 из заголовочного файла <numeric> можно использовать для расчета многих статистических параметров, а не только для суммирования пользовательских объектов-функций. Пример 11.9 показывает, как можно вычислить значения некоторых важных статистические функций при помощи accumulate.

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

#include <numeric>

#include <cmath>

#include <algorithm>

#include <functional>

#include <vector>

#include <iostream>

using namespace std;

template<int N, class T>

T nthPnwer(T x) {

 T ret = x;

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

  ret *= x;

 }

 return ret;

}

template<class T, int N>

struct SumDiffNthPower {

 SumDiffNthPower(T x) : mean_(x) {};

 T operator()(T sum, T current) {

  return sum + nthPower<N>(current - mean_);

 }

 T mean_;

};

template<class T, int N, class Iter_T>

T nthMoment(Iter_T first, Iter_T last, T mean) {

 size_t cnt = distance(first, last);

 return accumulate(first, last, T(), SumDiffNthPower<T, N>(mean)) / cnt;

}

template<class T, class Iter_T>

T computeVariance(Iter_T first, Iter_T last, T mean) {

 return nthMoment<T, 2>(first, last, mean);

}

template<class T, class Iter_T>

T computeStdDev(Iter_T first, Iter_T last, T mean) {

 return sqrt(computeVariance(first, last, mean));

}

template<class T, class Iter_T>

T computeSkew(Iter_T begin, Iter_T end, T mean) {

 T m3 = nthMoment<T, 3>(begin, end, mean);

 T m2 = nthMoment<T, 2>(begin, end, mean);

 return m3 / (m2 * sqrt(m2));

}

template<class T, class Iter_T>

T computeKurtosisExcess(Iter_T begin, Iter_T end, T mean) {

 T m4 = nthMoment<T, 4>(begin, end, mean);

 T m2 = nthMoment<T, 2>(begin, end, mean);

 return m4 / (m2 * m2) - 3;

}

template<class T, class Iter_T>

void computeStats(Iter_T first, Iter_T last, T& sum, T& mean,

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ОБРАНЕ

0

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

Отметить Добавить цитату