C ++ STL列表计算平均值

时间:2010-02-01 13:29:49

标签: c++ list stl average

我必须纠正一些C ++ / STL代码。不幸的是,我的C ++经验很少,对STL一无所知。不过我完成了大部分工作,但下面的功能仍然给我带来了问题:

C ++来源:

double MyClass::CalculateAvg(const std::list<double> &list)
{
    double avg = 0;
    std::list<int>::iterator it;
    for(it = list->begin(); it != list->end(); it++) avg += *it;
    avg /= list->size();
}

C ++标题:

static double CalculateAvg(const std::list<int> &list);

它最有可能是从列表中计算平均值,但它符合很多错误。我试图在网上搜索解决方案,但我找不到任何东西。如果有人可以帮助我,我会很高兴。

更新: 感谢您的快速回复。接受的答案解决了我所有的问题。

9 个答案:

答案 0 :(得分:32)

少数事情:

  1. 你没有退货。 (添加return avg;
  2. ->运算符用于指向对象。您有一个列表的引用,因此您使用list.begin()而不是list->begin()(其他成员函数也相同)
  3. 迭代器应该是const_iterator,而不是iterator
  4. 无论如何,您应该执行以下操作:

    return std::accumulate(list.begin(), list.end(), 0.0) / list.size();

    如果您的使用案例中有可能,可以选择检查list.size() == 0

答案 1 :(得分:13)

所以,第一个错误是:

std::list<int>::iterator it;

在整数列表上定义迭代器,并使用它迭代双精度列表。此外,迭代器只能用于非常量列表。你需要一个恒定的运算符。你应该写:

std::list<double>::const_iterator it;

最后,您忘记返回值。

编辑:我没有看到,但您将列表作为参考传递,但将其用作指针。因此请将所有list->替换为list.

答案 2 :(得分:4)

如何使用accumulate

答案 3 :(得分:2)

除了@PierreBdR的回答, 你还应该检查list-&gt; size()是否大于0,

就在这之前

  avg /= list.size();

添加

 if (list.size()>0) 
    //avg code here.

或者说明作为参数收到的列表不应为空。

   assert(list.size()>0)

答案 4 :(得分:2)

不是进行编辑以确保您的迭代器引用相同类型的列表,而是将代码编写为通用算法,并将迭代器类型作为模板参数,这样做会好得多。

我还要注意,对于std::list,您的原始代码大多数已发布的答案都存在相当严重的效率问题:给定典型的列表实现,它们会迭代列表一次添加值,然后再次执行以计算元素的数量。从理论上讲,list.size() 可以在不经过元素迭代的情况下运行,但事实上很少会出现这种情况(list::size()或{{1}可能会有不变的复杂性},但不是一次两个。)

我写的代码如下:

list::splice

这是通用的,所以当你意识到template <class fwdit> typename fwdit::value_type arithmetic_mean(fwdit begin, fwdit end) { typedef typename fwdit::value_type res_type; res_type sum = res_type(); size_t count = 0; for (fwdit pos = begin; pos!= end; ++pos) { sum += *pos; ++count; } return sum/count; } 是一个糟糕的选择时,它会继续工作(未改变),而你真的会更好地使用std::list。同样,如果你想要一些int的算术平均值而不是double的,它也可以处理它(同样,不改变代码)。第三,即使(如上所述)你的库的std::vector的实现恰好是线性的,这仍然只遍历列表一次,所以它可能是原始代码(工作版本)的两倍快。

当然,缓存可以(会)影响它 - 当你平均一个小列表时,第一次遍历会将整个列表拉入缓存,所以第二次遍历通常会快得多(所以消除第二次遍历)不会节省太多时间。)

答案 5 :(得分:1)

您传递了std::list<double>,但是您创建了一个std::list<int>迭代器?你的原型也需要std::list<int>

答案 6 :(得分:1)

正如Maurits Rijk所说,你没有返回平均值。另外,它编译的错误是什么?

答案 7 :(得分:1)

由于list是引用而不是指针,因此您不需要->解除引用运算符,而只需要.运算符,即it = list.begin()等等

此外,正如其他人都指出的那样,列表及其迭代器的模板类型参数都需要匹配:<int><double>。看起来该函数最初编写为接受double s的列表。

答案 8 :(得分:1)

为自己锻炼身体。一旦你开始工作,你应该把它变成for_each。从长远来看,它更容易理解。

- 编辑 -

Accumulate更好,因为它适用于二进制数值运算。