Функция для вычисления среднего значения массива double [] с использованием накопления - PullRequest
8 голосов
/ 26 октября 2011

Это, должно быть, самая распространенная функция для каждого фрагмента кода, но на самом деле я потратил не менее 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: «накапливать»: идентификатор не найден

Можете ли вы сказать мне, как исправить эту функцию?Что означает эта ошибка компиляции?

Если я использую std::accumulate (сверх уже определенного using namespace std), то получаю следующую ошибку:

'accumulate' : is not a member of 'std'
'accumulate': identifier not found

Почему «накопление» не является членом «std»?

ps: я знаю, что могу использовать способ sum + = array [i] и не использовать накопление, но я хотел бы понять, что здесь происходит и как я могу заставить мой пример работать.

Ответы [ 4 ]

24 голосов
/ 26 октября 2011

Попробуйте добавить

#include <numeric>

В результате появится нужная функция 'std :: аккумулировать'.

Если пойти дальше, у вас возникнет проблема с определением количества элементов в вашем массиве. Действительно, массив не может быть передан функции в надежде, что функция сможет узнать размер массива. Это будет распадаться на указатель. Следовательно, ваш count расчет будет неверным. Если вы хотите иметь возможность передавать заданный массив фактического размера, вы должны использовать шаблонную функцию.

template <int N>
double mean_array( double ( & array )[N] )
{
    return std::accumulate( array, array + N, 0.0) / (double)(N);
}
3 голосов
/ 26 октября 2011

Это не совсем вопрос, который вы задали, но в вашем примере кода есть простая ошибка. Начальное значение в 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;
}

или, что еще лучше, шаблонная версия от Didier Trosset

2 голосов
/ 26 октября 2011

Для использования std::accumulate необходимо включить соответствующий заголовок.Добавьте следующее в ваш исходный файл.

#include <numeric>
0 голосов
/ 26 октября 2011
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;
}

Если вы передаете массив функции, вы «теряете» его размер, поэтому вам нужно передать его в качестве параметра (он немного сложнее, чем этот ... но пока этого должно быть достаточно)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...