0

着信数値の平均値を報告する必要があります。何らかのデータ構造を使用してすべての値を追跡し、それらを合計して値の数で割って平均を計算することなく、どのようにそれを行うことができますか?

4

5 に答える 5

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))

于 2010-06-02T08:49:36.990 に答える
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 がレンダリングされます...

于 2010-06-02T08:59:20.900 に答える
1

現在の合計とカウントを維持します。着信番号ごとに両方を更新します。

avg = sum / count.
于 2010-06-02T08:39:13.430 に答える
1

平均を計算するために必要なのは、合計と受け取った数字の数だけです。

于 2010-06-02T08:39:24.520 に答える
0

合計を追跡する必要はなく、カウンターのみを追跡する必要があります。

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

from->長時間の平均化によるオーバーフローを防止しますか?

于 2010-07-23T07:55:20.210 に答える