2010-06-02 83 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?