2012-02-04 6 views
0

私はGoogleに回答を試みたが、間違ったキーワードを使用していると思う。私がしようとしているのは、 - 私は数値(ints)のコレクションを持って、私は新しい平均を計算している新しい数字を追加します。私は配列が大きくなるにつれて、ある要素の数(200とする)になると、計算時間が顕著になることに気付きました。私は私のコードのパフォーマンスをスピードアップするために利用できる内蔵のSDK関数があるのだろうかと思っていたのですか? Android上でコードを実行します。Javaの任意のSDK関数がスタックに番号をプッシュして平均を計算しますか?

sum -= oldest_value; 
sum += new_value; 
avg = (double)sum/num_elements; 

あなたがcircular bufferとしてあなたのアレイを使用する必要があり、あなたのアレイを介したびに、すべての要素をシフトすることを避けるために:

int[] numbers = new int[3]; 

private int average(int number){ 
    //some buildin operation to push in array an int? 
    for(int i=0; i < numbers.length -1 ; i++){ 
     numbers[i]=numbers[i+1]; 
    } 
    numbers[numbers.length -1] = number; 
        ;     
    //numbers[0] = numbers[1]; 
    //numbers[1] = numbers[2]; 
    //numbers[2] = number; 

    int sum = 0; 

    //any operation to get average? 
    for(int i=0; i < numbers.length ; i++) 
     sum = sum + numbers[i]; 

    //calculate average value 
    double average = sum/numbers.length; 

    return (int)average; 
} 
+2

は、あなたは配列内の平均値を取得したいですか? – Kris

+0

私はあなたの質問を全く理解していません。あなたは平均を計算したいが、問題は何ですか?あなたのコードの最初のループは何ですか? –

+0

この関数が正確に計算するために与えられていることを教えてください。 –

答えて

1

今私は自分自身を循環バッファーにしました(Oli Charlesworth)。

そして、これが私の実装です:まさにあなたが達成しようとしているかわからない

/** Circular buffer */ 
private class WindowBuffer { 
    private final float [] values; 
    private final int capacity; 
    private float sum; 
    private float average; 
    private int head = -1; 
    private boolean full = false; 

    WindowBuffer(final int capacity) { 
     this.capacity = capacity; 
     values = new float[capacity]; 
     for (int i = 0; i < capacity; i++) { 
      values[i] = 0f; 
     } 
    } 
    void clean() { 
     if (head == -1) return; 
     for (int i = 0; i < capacity; i++) { 
      values[i] = 0f; 
     }    
     sum = 0; 
     average = 0; 
     head = -1; 
     full = false; 
    } 

    void put(final float value) { 
     head++; 
     if (head >= capacity) { 
      head = 0; 
      full = true; 
     } 
     sum -= values[head]; 
     sum += value; 
     values[head] = value; 
     calculateAverage(); 
    } 

    private void calculateAverage() { 
     if (full) { 
      average = sum/capacity; 
     } else { 
      average = sum/(head + 1); 
     } 
    } 

    float getAverage() { 
     return average; 
    } 
} 

UPD

void clean() { 
      if (head == -1) return; 
      if (full) { 
       for (int i = 0; i < capacity; i++) { 
        values[i] = 0f; 
       } 
      } else { 
       for (int i = 0; i <= head; i++) { 
        values[i] = 0f; 
       } 
      } 
      sum = 0; 
      average = 0; 
      head = -1; 
      full = false; 
     } 
+0

感謝!これはほとんど何が起こったかです。私が最初に持っていたものより速い – Hia

+0

ありがとう、しかし私は私の提案が高く評価されているのを見ていない;) また、私はclean()fuctionを切り捨てました。 – Silver

+0

私の謝罪:)それは今認められている! – Hia

3

(整数タイプの)移動平均を効率的のように計算することができます。

+0

はい。わかります。これは私が探していたものです。 – Hia

0

私があなたの場合、私はArrayListを使用していたでしょう。コードとまったく同じことをするコードを見てください。

ArrayList<Integer> numbers = new ArrayList<Integer>(); 
private Integer average(Integer number){ 
    numbers.add(number); 
    Integer sum = 0;  
    for(Integer num : numbers) { 
     sum = sum + num; 
    } 
    double average = sum/numbers.size(); 
    return (Integer)average; 
} 

そして、あなたは再利用のための変数の和を保存することができた場合にも、あなたは確かに新しい平均値を見つける方法を知っている:)

0

平均値を算出し、より良いalgotithmはありません。 (同じデータ構造を使用して)最適化されたコードは次のようになります。ご質問や、あなたのコードを理解するのに苦労し

private int average(int number){ 
     int sum = 0; 
     for(int i=0; i<(numbers.length-1); i++){ 
      numbers[i] = numbers[i+1]; 
      sum += numbers[i]; 
     } 
     numbers[numbers.length -1] = number; 

     return (int)((sum+number)/numbers.length); 
} 
+0

**ランニング**平均を計算するためのより良いアルゴリズムがあります。 –

+0

でも、最初に和を知る必要があります...複雑さは少なくとも 'O(n)'でなければなりません。 – zambotn

+0

入力データの無限ストリームを仮定すると、償却された複雑さはO(1)です。そして、とにかく起動時に 'sum = 0'と仮定します。 –

0

イム。最初のループが何のためにあるのか全く分かりません。

が、あなたは自分のかなりの右

int sum =0; 
for(int i=0; i<array.length();i++){ 
    sum=sum+array[i]; 
} 
average = sum/array.length(); 

ない最速の方法を見つける。平均してしようとしているが、すべて簡単には少し遅れて

+0

=)私は英語にも問題があります。 私が持っているのは、新しい数値が配列の平均サイズよりも固定されたサイズ(最初は最後のもの)にプッシュされたものです。配列で他の操作を実行する。もう一度...ループ内で – Hia

+0

私はこれがまだ見つかるだろうと理解していますが、他の操作が平均ループの内側にないことを確認してください – TrewTzu

+0

ああ、あなたはOli Charlesworthの答えから今何を意味しているのか分かります。あなたは何かを押してからポップして再計算しています。あなたが答えを見つけられたらうれしいです。 – TrewTzu

1

を読み取ることが、ここでは一つの方法だ場合:

public class RunningAverage 
{ 
    ArrayList<Integer> numList = new ArrayList<Integer>(); 
    private int runningSum = 0; 
    private int sampleSize; 
    public RunningAverage(int[] initialSetOfValues) 
    { 
     if(initialSetOfValues == null || initialSetOfValues.length == 0) 
     { 
      // Abort gracefully 
      // left as an exercise... 
     } 
     sampleSize = initialSetOfValues.length; 
     for (int num : initialSetOfValues) 
     { 
      numList.add(num); 
      runningSum += num; 
     } 
    } 

    public int getRunningAverage(int newestVal) 
    { 
     numList.add(newestVal); 
     int oldestVal = numList.remove(0); 

     runningSum = runningSum - oldestVal + newestVal; 
     return runningSum/sampleSize; 
    } 

    public static void main(String args[]) 
    { 
     RunningAverage r = new RunningAverage(new int[]{4, 5 , 6, 7}); 
     System.out.println(r.getRunningAverage(8)); 
     System.out.println(r.getRunningAverage(9)); 
     System.out.println(r.getRunningAverage(10)); 
    } 
} 
関連する問題