【发布时间】:2010-06-02 08:37:39
【问题描述】:
我必须报告传入数字的平均值,如果不使用某种数据结构来跟踪所有值,然后通过将它们相加并除以值的数量来计算平均值,我怎么能做到这一点?
【问题讨论】:
我必须报告传入数字的平均值,如果不使用某种数据结构来跟踪所有值,然后通过将它们相加并除以值的数量来计算平均值,我怎么能做到这一点?
【问题讨论】:
只需不断计算总和以及您收到多少个数字,这就是计算平均值所需的全部内容。
【讨论】:
如果我没记错的话,也可以这样计算avg(n+1):
avg(n+1) = (a[1]+ ... + a[n+1]) / (n+1) =
= (a[1]+ ... + a[n])/(n+1) + a[n+1]/(n+1) =
= (n(a[1]+ ... + a[n])/n) / (n+1) + a[n+1]/(n+1) =
= n*avg(n) / (n+1) + a[n+1]/(n+1) =
= n/(n+1) * avg(n) + a[n+1]/(n+1)
所以将旧的平均值乘以n/(n+1),然后加上新元素除以n+1。根据n 的高度以及您的值有多大,这可以减少舍入误差...
编辑:当然你必须使用浮点数计算n/(n+1),否则它总是会呈现 0...
【讨论】:
如果您有数字 a[1] a[2] ... a[n] 并且您知道它们的平均值是 avg(n) = (a[1] + ... + a[n]) / n,那么当您获得另一个数字 a[n + 1] 时,您可以这样做:
avg(n + 1) = (avg(n) * n + a[n + 1]) / (n + 1)
一些浮点错误是不可避免的,但您应该对此进行测试,看看它是否足够好。
为了避免溢出,你可以先做除法:
avg(n + 1) = (avg(n) / (n + 1)) * n + (a[n + 1] / (n + 1))
【讨论】:
保持当前的总和和计数。更新每个传入号码。
avg = sum / count.
【讨论】:
您不需要跟踪总和,只需计数器:
class Averager {
float currentAverage;
size_t count;
float addData (float value) {
this->currentAverage += (value - this->currentAverage) / ++count;
return this->currentAverage;
}
}
【讨论】: