2013-10-04 42 views
0

我需要一個程序來計算一組數字的移動平均值(我使用4, 9,3.14,1.59,86.0,35.2,9.98,1.00,0.01,2.2,和3.76)。當我運行這個時,它會打印出 「17.859999999999996」九次。你們有沒有看到任何錯誤?如何在Java中創建移動平均數

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]); 
     } 
    } 
} 
+1

當您使用調試程序執行程序時,或者在循環中插入'println'調用以查看中間值時,您看到了什麼? – Simon

回答

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

因爲這看起來像一個任務,我會給你一個提示。

移動平均具有窗口。在這種情況下,窗口的寬度是averageLength。這是您平均得分的點數。

你需要在創建移動平均環以某種方式使用averageLength。你現在不是。

1

你內在的for迭代所有的數組,所以你總是得到相同的平均值(整個數組的一個),你應該從0迭代到外部for的當前數。

你的移動平均線是基於在你的內心forj更新;這意味着它會覆蓋先前值的每個新循環,這應該是外for,而不是使用作爲i索引內層一個的內部。

您將除以sum/j來計算平均值,每個新的內部循環j您將除以0第一個sum。我相信你的意思是使用j+1相反,指數是不一樣的current length

技巧來解決:

避免使用變量循環數組,你應該使用array.length來代替。

爲了重現您的問題的問題,你可以給我們孤立的問題,而不是你當前的代碼...即:

double[] data = new double[] { 1, 5, 8 }; //your real inputs. 
double[] movingAverage = new double[data.length]; 
for (int i = 0; i < data.length; i++) { 
    double sum = 0.0; 
    for (int j = 0; j <= i; j++) { 
    ... 
    } 
} 

試想一下,如果錯誤是在你的投入,我們怎麼能相信你真的使用它們?

0

下一次,大約需要轉讓的評論無從談起您發佈之前。但是,既然你在這方面看起來很新穎,那就考慮一下你將如何瀏覽這些數據,並讓它做到這一點。你應該試着確保每個循環都停在正確的點上,並且記住,如果你在沒有更多數字的時候停下來(比如當你在做內部循環時,你只能得到3個數字而不是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代碼,但這是主意。

0

沒有任何額外的細節,您可能需要一個未加權的移動平均線。在長度爲N(與0<=i<N)的輸入數組A中的任何點A[i],這僅僅是之前K條目的平均值,直到幷包括A[i]。如果不存在K這樣的值,那麼平均A[0]A[i]的值(i+1),包括端點值。

有一點思想會告訴你,你不需要每次加起來所有的K值。只要保持總和,當移動到下一個點(此是「移動」平均值)時,減去正在替換的值並添加將替換它的新值。 (在第一個K-1點中,你只需將新值加到總和上並將你的計數器增加1.)

在這個過程中的任何點,移動平均值是當前總和除以當前值計數值。