【问题标题】:Function for calculating the mean of an array double[] using accumulate使用累积计算数组 double[] 平均值的函数
【发布时间】:2011-12-15 12:01:57
【问题描述】:

对于每个人在某处都有代码sn-p的东西,它一定是最常见的功能,但我实际上已经花了不少于1.5小时在SO以及其他C++网站上搜索它,但还没有找到解决方案。

我想使用函数计算double array[] 的平均值。我想将数组作为 reference 传递给函数。有数百万个示例在 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

为什么 'accumulate' 不是 'std' 的成员?

ps:我知道我可以使用 'sum += array[i]' 方式而不使用累积,但我想了解这里发生了什么以及如何使我的示例正常工作。

【问题讨论】:

  • 我不确定,只是想知道,您是否添加了必要的包含文件?
  • 小心:accumulate( array, array + count, 0.0 ); 注意 0.0 - 您在代码 sn-p 中累积整数。
  • 那么,如果我从 0.0 开始,效果好吗?我需要传递计数,还是可以从 sizeof 计算?
  • 您不能使用sizeof(array),因为数组的大小未知。在这种情况下,请参阅下面的@xanatos 答案以获得更好的方法。
  • 顺便说一句,在这里使用 std::accumulate 很好。如果您的数组非常大,则可以将其与例如 __gnu_parallel::accumulate 简单地平行化。

标签: c++ arrays visual-studio-2010 stl std


【解决方案1】:

这并不完全是您提出的问题,但在您的代码示例中存在一个简单的错误。 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】:

    尝试添加

    #include <numeric>
    

    它将引入您正在寻找的 'std::accumulate' 函数。

    更进一步,您将很难找出数组中的元素数量。实际上,不能将数组传递给函数,希望函数能够知道数组的大小。它将衰减为指针。因此,您的count 计算将是错误的。如果您希望能够传递一个实际大小的指定数组,则必须使用模板函数。

    template <int N>
    double mean_array( double ( & array )[N] )
    {
        return std::accumulate( array, array + N, 0.0) / (double)(N);
    }
    

    【讨论】:

    • 我不确定这个模板函数是否可以在 Objective-C 方法(包装器)中调用。 @didier-trosset:您能否详细说明模板如何帮助计数?如果我必须从我已经拥有 count 的 Objective-C 调用 C++ 函数,您是否同意不再需要模板,因为 count 作为该函数的第二个参数传递?
    • @KushalAshok 正确。要么将指针和计数传递给非模板函数;或者你只将一个数组传递给一个模板函数(这将猜测计数)。
    • 感谢您的确认。我确实通过了指针和计数,但在通过 Instruments 运行时找不到任何内存泄漏
    【解决方案3】:

    要使用std::accumulate,您需要包含适当的标题。将以下内容添加到您的源文件中。

    #include <numeric>
    

    【讨论】:

    • 好的,看来这是我错过的那个。我有很多包含,我错过了。
    【解决方案4】:
    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;
    }
    

    如果你将一个数组传递给一个函数,你会“丢失”它的大小,所以你必须将它作为一个参数传递(它比这更复杂一些......但现在它应该足够了)

    【讨论】:

    • 但我不明白,它不是和int count = sizeof( array ) / sizeof( array[0] );一起工作的吗?
    • If you pass an array to a function, you "lose" its size, so you have to pass it as a parameter 的哪一部分不清楚? sizeof(array) is == sizeof(double*) 那时。如果将数组传递给函数,则会丢失数组的大小。如果您不信任我,请尝试调试它。
    • @zsero:当您将数组作为函数参数传递时,它会衰减为指针。这不再是数组类型并且“丢失”了大小。通常,您也会像 xanatos 的示例一样将大小作为单独的参数传递。
    • 好的,现在很清楚了。我不知道它“衰减”为指针。感谢您的代码和解释。
    猜你喜欢
    • 2012-06-19
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 2016-07-11
    • 1970-01-01
    相关资源
    最近更新 更多