You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java计算简单移动平均时多余首元素、数组越界问题求解

问题根因

两个问题本质都是没有区分环形缓冲区的填充阶段和有效计算阶段:

  • 首个无效值6.0:buffer数组初始化时默认填充0,第一次循环仅写入了第一个元素12/2=6,剩余buffer位还是初始0,此时窗口尚未攒够n=2个有效数据,计算出的结果自然无效。
  • 数组下标越界:原逻辑每遍历一个输入数据就往output数组写一个值,但有效结果总长度为data.length -n +1,当写入位置超过output数组长度时就会触发越界。
修正实现

核心调整逻辑:

  • 输出数组直接按有效长度data.length -n +1初始化,不用先开长数组再剔除无效值
  • 前n-1个输入数据仅写入环形缓冲区,不触发结果计算和输出
  • 从第n个数据(对应下标i=n-1)开始,每写入一个缓冲区数据就计算一次移动平均值,写入输出数组
  • 单独维护输出数组的写入下标,不和输入遍历下标混用

修正后可直接运行的代码:

public class SimpleMovingAverage {
    public static void main(String[] args) {
        int windowSize = 2;
        double[] inputData = {12, 13, 15, 7, 6, 9, 13};
        
        // 基础参数校验
        if (windowSize < 1 || windowSize > inputData.length) {
            throw new IllegalArgumentException("窗口大小必须在1到输入数据长度之间");
        }

        double[] ringBuffer = new double[windowSize];
        double[] result = new double[inputData.length - windowSize + 1];
        int bufferPos = 0;
        int resultPos = 0;

        for (int i = 0; i < inputData.length; i++) {
            // 最新数据写入环形缓冲区
            ringBuffer[bufferPos] = inputData[i] / windowSize;
            bufferPos = (bufferPos + 1) % windowSize;

            // 窗口填满后才开始计算有效均值
            if (i >= windowSize - 1) {
                double ma = 0.0;
                for (double num : ringBuffer) {
                    ma += num;
                }
                result[resultPos++] = ma;
            }
        }

        // 验证输出,结果为[12.5, 14.0, 11.0, 6.5, 7.5, 11.0],与预期一致
        for (double val : result) {
            System.out.println(val);
        }
    }
}
可选优化

如果数据量较大,可以维护一个实时累加的总和变量,不用每次计算MA都遍历整个缓冲区求和,把时间复杂度从O(m*n)降到O(m)(m为输入数据长度):

// 优化后求和逻辑,无需内层循环
double total = 0.0;
for (int i = 0; i < inputData.length; i++) {
    // 先减去缓冲区里即将被覆盖的旧值
    total -= ringBuffer[bufferPos];
    ringBuffer[bufferPos] = inputData[i] / windowSize;
    // 加上新写入的值
    total += ringBuffer[bufferPos];
    bufferPos = (bufferPos + 1) % windowSize;

    if (i >= windowSize -1) {
        result[resultPos++] = total;
    }
}

内容的提问来源于stack exchange,提问作者judo_ürgens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 18:57:23