Функция для вычисления среднего значения массива double [] с помощью accumulate
Это должна быть самая распространенная функция для того, что у каждого где-то есть фрагмент кода, но я на самом деле потратил не менее 1,5 часа на его поиск на SO, а также на других сайтах C++ и не нашел решения.
Я хотел бы вычислить среднее значение double array[]
с помощью функции. Я хотел бы передать массив функции в качестве ссылки . Есть миллионы примеров, когда среднее вычисляется в цикле main (), но то, что я ищу, - это функция, которую я могу поместить во внешний файл и использовать его в любое время позже.
До сих пор, вот моя последняя версия, что дает ошибку компиляции:
double mean_array( double array[] )
{
int count = sizeof( array ) / sizeof( array[0] );
double sum = accumulate( array, array + count, 0 );
return ( double ) sum / count;
}
Ошибка компиляции:
Ошибка C3861: 'accumulate': идентификатор не найден
Подскажите, как исправить эту функцию? Что означает эта ошибка компиляции?
Если я использую std::accumulate
(над уже определенным using namespace std
), то я получаю следующую ошибку:
'accumulate' : is not a member of 'std'
'accumulate': identifier not found
Почему "накопить" не является членом "ЗППП"?
p. s.: Я знаю, что могу сделать 'sum += array[i]' способом и не использовать accumulate, но я хотел бы понять, что здесь происходит и как я могу заставить мой пример работать.
4 ответов:
Попробуйте добавить
#include <numeric>
Это приведет к функции 'std:: accumulate', которую вы ищете.
Идя дальше, вы столкнетесь с проблемой, чтобы узнать количество элементов в вашем массиве. Действительно, массив не может быть передан функции в надежде, что функция сможет узнать размер массива. Он распадется на указатель. Поэтому ваш расчет
count
будет неверным. Если вы хотите иметь возможность передать заданный массив фактического размера, вы должны использовать шаблон функция.template <int N> double mean_array( double ( & array )[N] ) { return std::accumulate( array, array + N, 0.0) / (double)(N); }
Это не совсем тот вопрос, который вы задали, но в вашем примере кода есть простая ошибка. Начальное значение в
accumulate
является шаблоном, а в вашем коде-шаблоном целых чисел. Если вы передадите ему набор двойников, они будут приведены к целым числам, и вы получите неправильные ответы. Сделав эту ошибку раньше, я сделал себе быструю гарантию следующим образом:/** Check that not inputting integer type into accumulate * This is considered an error in this program (where a double was expected * @tparam InputIterator The iterator to accumulate * @tparam T The type to accumulate - will fail if integer. * @param first The first iterator to accumulate from. * @param last the iterator to acculate to, * @param init The initial value * @return The accumulated value as evaluated by std::accumulate. */ template<class InputIterator, class T> inline T accumulate_checked(InputIterator first, InputIterator last, T init ) { return std::accumulate(first,last, init); } //Not implemented for integers (will not compile if called). template<class InputIterator> inline int accumulate_checked(InputIterator first, InputIterator last, int init );
Подумал, что я поделюсь им, если это будет интересно.
Просто для полноты ваша функция может выглядеть например:
double mean_array( double *array, size_t count ) { double sum = std::accumulate(array,array+count,0.0) return sum / count; }
Или быть особенно осторожным
double mean_array( double *array, size_t count ) { double sum = accumulate_checked(array,array+count,0.0) return sum / count; }
Или еще лучше шаблонная версия от Дидье троссе
Для использования
std::accumulate
необходимо включить соответствующий заголовок. Добавьте в исходный файл следующее.#include <numeric>
double mean_array( double *array, size_t count ) { double sum = 0.0; for (size_t i = 0; i < count; i++) { sum += array[i]; } return sum / count; }
Или
double mean_array( double *array, size_t count ) { double sum = 0.0; double *pastLast = array + count; while (array < pastLast) { sum += *array; array++; } return sum / count; }
Если вы передаете массив функции, вы "теряете" его размер, поэтому вы должны передать его в качестве параметра (это немного сложнее, чем это... но пока этого должно быть достаточно)
Comments