-3

コンストラクターでステップサイズ(n)を受け取るクラスを記述します。クラス内の唯一のメソッドは整数を受け取り、それを数値のシーケンスに追加し、シーケンスに挿入された最後のn個の値の平均を返します。平均を計算するためにシーケンスを繰り返さないでください。

いいえ、これは宿題ではありません

以下は、C++でそれを行う私の方法です。

  1. 2つのSTLqueue<int>を初期化します。そのうちの1つには長さnがあり、buffer
  2. ユーザー入力値はバッファに動的に保存されます。これbufferがいっぱいになったら、ユーザー入力値を「合計」に追加し、値を減算しbuffer.front()ます。
  3. buffer最初の値をから2番目のqueue<int>名前の値にプッシュしますvalues
  4. 最初の値をポップします(buffer.pop()
  5. で割って平均を返しsumますn

以下は私が思いついたコードです:

#ifndef calcAverage_Window_h
#define calcAverage_Window_h

#include <iostream>
#include <queue>
using namespace std;

class Window{
private:
    int n, sum;
    queue<int> values, buffer, sums;

public:
    Window(int);
    float calcAverage(int);
};

#endif


#include "Window.h"

Window::Window(int m){
    n = m;
    buffer.push(1);
    buffer.push(2);
    buffer.push(3);
    sum = 6;
}

float Window::calcAverage(int val){
    buffer.push(val);
    values.push(buffer.front());
    sum = sum + val - buffer.front();
    buffer.pop();

    return float(sum)/n; //float(sum) required so that calcAverage doesn't return an int
}


#include "Window.h"

int main()
{
    Window w(3);
    cout<<w.calcAverage(4)<<endl;
    cout<<w.calcAverage(5)<<endl;
    cout<<w.calcAverage(6)<<endl;
    return 0;
}

次の質問があります。

  1. これを行うためのより良い方法はありますか?
  2. STLの使用も許可されていない場合は、キューを実装し、それをとに使用しbufferますvalues。誰かもっと良いアイデアがありますか?
  3. Window(n)コンストラクターでバッファーを初期化することで少しだましました。これは、次の理由によるものです。1)他にどのように対処するかわからなかった2)の場合は明らかかもしれませんが、の場合n = 2はあいまいですn = 3
  4. このメソッド/コードはどこで失敗しますか?
  5. 私は経験的にこのように考えるようになりました。この問題を調べるアルゴリズム的な方法はありますか?
4

1 に答える 1

3

いくつかの質問に答えるには:


このメソッド/コードはどこで失敗しますか?

上記のコードにバグがないと仮定すると、浮動小数点データに移動することにした場合、必ずしも正しく機能するとは限りません。

そのオーバーフロー動作も、移動平均の直接実装とは微妙に異なることに注意してください。


この問題を調べるアルゴリズム的な方法はありますか?

はい。ウィンドウサイズの場合、時間と時間Lの移動合計は次のようになります。nn-1

y[n]   = x[n] + x[n-1] + ... + x[n-L+1]
y[n-1] =        x[n-1] + ... + x[n-L+1] + x[n-L]

一方の方程式をもう一方の方程式から引くと、次のようになります。

y[n] - y[n-1] = x[n] - x[n-L]

y[n-1]等号の反対側に移動すると、完了です。

于 2013-03-19T21:09:03.260 に答える