如何在Java中创建移动平均线

时间:2013-10-04 20:38:06

标签: java arrays for-loop moving-average

我需要一个程序来计算一组数字的移动平均值(我使用4, 9,3.14,1.59,86.0,35.2,9.98,1.00,0.01,2.2和3.76)。当我运行它时,它打印出来 “17.859999999999996”九次。你们看到有什么错误吗?

import java.util.*;

public class MovingAverage
{
    public static void main(String args[])
    {
        Scanner scan = new Scanner(System.in);
        // Read in the length of the moving average and the number
        // of data points
        int averageLength = scan.nextInt();
        int numDataPoints = scan.nextInt();
        // Create an array to hold the data points, and another to
        // hold the moving average
        double data[] = new double[numDataPoints];
        double movingAverage[] = new double[numDataPoints];
        // Read in all of the data points using a for loop
        for(int i = 0; i< numDataPoints; i++)
        {
            data[i]=scan.nextDouble();
        }
        // Create the moving average
        for (int i=0; i<numDataPoints; i++) 
        {
            // Calculate the moving average for index i and put
            // it in movingAverage[i]. (Hint: you need a for
            // loop to do this. Make sure not to use i as your
            // loop variable. Also, make sure to handle the
            // case where i is not large enough (when i<averageLength-1). 
            double sum= 0.0;
            for(int j=0; j<numDataPoints; j++)
            {

                sum=sum+data[j];
                movingAverage[i]=sum/j;
            }

        }
        // Print the moving average, one value per line
        for (int i=0; i<numDataPoints; i++)
        {
            System.out.println(movingAverage[i]);
        }
    }
}

6 个答案:

答案 0 :(得分:3)

由于这看起来像是一项任务,我会给你一个提示。

移动平均线有一个窗口。在这种情况下,窗口的宽度为averageLength。这是你平均的点数。

你需要在创建移动平均线的循环中以某种方式使用averageLength。你现在不行。

答案 1 :(得分:1)

你的内部for正在迭代所有数组,这就是为什么你总是得到相同的平均值(整个数组的那个),你应该从0迭代到外部for的当前数字代替。

您的移动平均线正在根据内部j的{​​{1}}进行更新;这意味着它将覆盖每个新循环的先前值,这应该在外部for内,而不是使用for作为索引的内部值。

您要将i除以计算平均值,每个新内圈sum/j除以j第一个0。我认为您的意思是使用sum,而索引与j+1

不同

排查提示:

避免使用变量来循环数组,您应该使用current length代替。

如果要重现您的问题,您可以向我们提供孤立的问题,而不是您当前的代码...即:

array.length

想象一下,如果错误出现在您的输入中,我们怎么能相信您真的使用过它们?

答案 2 :(得分:0)

每次都循环遍历所有数据。你的内心平均值应该for(int j=(i>=averageLength?i-averageLength/2:0); j< i+averageLength/2 && j<numDataPoints; j++)(或类似的东西)。

此外,应修改movingAverage[i]=sum/j;以处理j0时的情况。特别是它应该是movingAverage[i]=sum/averageLength;,它应该应用于平均循环之外的movingAverage[i]槽。

答案 3 :(得分:0)

下次,在发布之前,请先解答有关该作业的评论。但是,既然你看起来很陌生,那么考虑一下如何浏览数据,然后让它做到这一点。你应该尝试确保每个循环都停在正确的位置,并记住,如果你没有更多的数字就会停止,(比如你在做内循环而你只能得到3个数而不是4个)该计划也需要停止。确保您的代码正在检查此内容。

答案 4 :(得分:0)

在移动平均线中,您需要具有某种窗口大小。

您的窗口大小是averageLength,因此它看起来像这样:

    if(i <averageLength-1)
    {
        double sum= 0.0;

        for(int j = 0; j < averageLength; j++)
        {
            sum += data[i-j];
        }

        movingAverage[i]=sum/averageLength;
    }

for循环从当前数据开始,然后返回averageLength数据点并将它们相加。当您拥有足够的数据点时,您将只有移动平均线,平均值将是总和除以平均长度。

注意:没有测试过sudo代码,但这是个主意。

答案 5 :(得分:0)

如果没有任何其他细节,您可能需要一个未加权的移动平均线。在长度为A[i](带A)的输入数组N中的任何点0<=i<N,这只是数组之前K条目的平均值,最多包括A[i]。如果没有K这样的值,则将(i+1)的{​​{1}}值从A[0]平均到A[i]

一点点思考就会向您显示您不需要每次都添加所有K值。只需保留总和,当移动到下一个点(此 “移动”平均值)时,减去要替换的值并添加将替换它的新值。 (在第一个K-1点期间,您只需将新值添加到总和中并将计数器增加1.)

在此过程中的任何时刻,移动平均线是当前总和除以当前计数值。