2010-06-02 119 views
0

我必须报告传入数字的平均值,我怎么能做到这一点,而不使用某种数据结构来跟踪所有值,然后通过求和和除以值的数量来计算平均值?平均越来越多的变量

+0

http://stackoverflow.com/questions/895396/how-do-i-find-在一个大的数字集合 – PRR 2010-06-02 09:09:43

回答

1

保持当前总数和数量。更新每个来电号码。

avg = sum/count. 
+0

它可能是一个简单的解决方案,但我不能使用这个简单的方法,因为浮点数的精度有限 - 我有大量的数字传入每秒,所以总和会变得​​非常大的数量和一些浮点错误将发生... – Oscar 2010-06-02 08:44:42

+0

@Oscar:那么你应该在你的问题中指定这个限制。就目前而言,你的问题并不复杂! – 2010-06-02 08:48:27

+0

@Dan:这是一个众所周知的平均浮点数的问题,当总结大量数字时应该总是考虑这个问题。 – Joey 2010-06-02 08:53:04

1

只要保持运行总和以及您已收到多少个数字,那就是您需要计算平均值的全部内容。

1

如果您有数字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))

1

如果我不能完全错误的,我们可以计算出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 ...

0

你不需要跟踪总和,只有柜台:

class Averager { 
    float currentAverage; 
    size_t count; 
    float addData (float value) { 
     this->currentAverage += (value - this->currentAverage)/++count; 
     return this->currentAverage; 
    } 
} 

从 - >prevent long running averaging from overflow?