我需要一个程序来计算一组数字的移动平均值(我使用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]);
}
}
}
答案 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;
以处理j
为0
时的情况。特别是它应该是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.)
在此过程中的任何时刻,移动平均线是当前总和除以当前计数值。