Функция для вычисления среднего значения массива 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