计算序列中元素的平均值,而不遍历它

Calculating averages of elements in a sequence without iterating over it

本文关键字:遍历 平均值 元素 计算      更新时间:2023-10-16

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

不,这不是作业

下面是我在c++中做的方法:

  1. 初始化两个STL queue<int>,其中一个长度为n,称为buffer
  2. 用户输入值动态存储在缓冲区中。一旦buffer满了,将用户输入的值加到"sum"上,然后减去buffer.front()的值。
  3. buffer的第一个值压入名为values的第二个queue<int>
  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,我将实现一个队列,并使用buffervalues。有人有更好的主意吗?
  3. 我通过在Window(n)构造函数中初始化缓冲区来欺骗了一点。这是因为:1)我不知道还能怎么做2)对于n = 2的情况可能是清楚的,但对于n = 3则是模糊的。
  4. 这个方法/代码在哪里会失败?
  5. 我是凭经验来思考这个问题的。有没有一种算法方法来看待这个问题?

回答你的几个问题:


这个方法/代码在哪里会失败?

好吧,假设上面的代码没有错误,如果你决定转移到浮点数据,它不一定能正确工作。

注意,与直接实现移动平均线相比,它的溢出行为也有微妙的不同。


有没有一种算法方法来看待这个问题?

是的。当窗口大小为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]移到等号的另一边,就完成了