LintCode-642: Moving Average from Data Stream

本文介绍了一种使用双端队列(deque)实现滑动窗口平均值的方法,并提供了详细的C++代码示例。该方法可以高效地计算最近N个整数的平均值,适用于实时数据流处理场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接用deque做的,好像也可以用queue和vector做。下次补充。

class MovingAverage {
public:
    /*
    * @param size: An integer
    */MovingAverage(int size) : sum(0), _size(size) {
    }

    /*
     * @param val: An integer
     * @return:  
     */
    double next(int val) {

        if (wind_rt.size() == _size) {
            sum -= wind_rt.front();
            wind_rt.pop_front();
            wind_rt.push_back(val);
            sum += val;
            return sum/_size;
        } else {
            wind_rt.push_back(val);
            sum += val;
            return sum/wind_rt.size();
        }    
    }
private:
    deque<int> wind_rt;
    int _size;
    double sum;
};

/**
 * Your MovingAverage object will be instantiated and called as such:
 * MovingAverage obj = new MovingAverage(size);
 * double param = obj.next(val);
 */
### Verilog 实现数据流水线及求平均值 #### 3.1 数据流水线概念 在硬件描述语言Verilog中,构建数据流水线可以显著提高处理速度和效率。流水线技术允许多个操作并行执行,在不同阶段同时处理不同的指令或数据。 #### 3.2 平均值计算原理 为了实现高效的平均值计算,通常采用累加器来累积输入数据,并在一个周期结束时除以样本数量得到最终结果。这种方法适用于固定长度窗口内的平均值计算。 #### 3.3 示例代码展示 下面是一个简单的Verilog代码示例,用于说明如何利用流水线结构来进行8个连续数据点的平均值计算: ```verilog module moving_average #( parameter WIDTH = 32, // Data width parameter DEPTH = 8 // Number of samples to average over )( input wire clk, input wire rst_n, input wire signed [WIDTH-1:0] din, // Input data stream output reg signed [WIDTH-1:0] dout // Output averaged value ); // Internal registers for storing the sliding window values reg signed [WIDTH-1:0] fifo[DEPTH-1:0]; integer i; always @(posedge clk or negedge rst_n) begin : proc_fifo_shift if (!rst_n) begin for (i = 0; i < DEPTH; i = i + 1) fifo[i] <= {WIDTH{1'b0}}; end else begin fifo[0] <= din; for (i = 1; i < DEPTH; i = i + 1) fifo[i] <= fifo[i-1]; end end // Accumulator and divider logic wire signed [WIDTH+$clog2(DEPTH):0] sum; assign sum = {{fifo[0]},{{(WIDTH-$clog2(DEPTH)){1'b0}}}} + {{fifo[1]},{{(WIDTH-$clog2(DEPTH)){1'b0}}}} + ... {{fifo[DEPTH-1]},{{(WIDTH-$clog2(DEPTH)){1'b0}}}}; assign dout = sum >> $clog2(DEPTH); // Divide by number of elements in FIFO endmodule ``` 此模块接收一系列宽度为`WIDTH`的数据流作为输入(`din`),并通过内部FIFO缓冲区保存最近的`DEPTH`个样本来形成滑动窗口[^3]。每当有新的数据到来时,旧的数据会被移出队列,新数据则进入队首位置。随后通过对这些存储单元中的所有数值求和再右移相应位数(相当于除法运算)得出当前时刻下的平均值输出给外部使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值