-3

编写一个在其构造函数中采用步长 (n) 的类。该类中唯一的方法接受一个整数,将其添加到一个数字序列中,并返回插入该序列的最后 n 个值的平均值。不要遍历序列来计算平均值。

不,这不是家庭作业

以下是我在 C++ 中的做法:

  1. 初始化两个 STL queue<int>,其中一个有长度n并且被称为buffer
  2. 用户 - 输入值动态存储在缓冲区中。填满后buffer,将用户输入值添加到“sum”并减去该buffer.front()值。
  3. 将第一个值推buffer入第二个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,我会实现一个队列并将其用于bufferand 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 回答