我必须纠正一些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);
它最有可能是从列表中计算平均值,但它符合很多错误。我试图在网上搜索解决方案,但我找不到任何东西。如果有人可以帮助我,我会很高兴。
更新: 感谢您的快速回复。接受的答案解决了我所有的问题。
答案 0 :(得分:32)
少数事情:
return avg;
)->
运算符用于指向对象。您有一个列表的引用,因此您使用list.begin()
而不是list->begin()
(其他成员函数也相同)const_iterator
,而不是iterator
。无论如何,您应该执行以下操作:
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)