简体   繁体   English

Java中是否有任何SDK函数可将数字推入堆栈并计算平均值?

[英]Any SDK function in Java to Push number unto a Stack and calculate the average?

I tried to Google for an answer but I think I am using wrong keywords. 我尝试向Google寻求答案,但我认为我使用了错误的关键字。 What I am trying to do is - I have a collection of numbers (ints), and as I add new numbers I am computing the new average. 我正在尝试做的是-我有一个数字(int)集合,当我添加新数字时,我正在计算新的平均值。 I noticed that as my array grows, once I get to a certain count of elements (lets say 200), the calculation time becomes noticeable. 我注意到随着数组的增长,一旦达到一定数量的元素(比如说200),计算时间就会变得很明显。 I was wondering if there are any built-in SDK functions I can utilize to speed up my codes performance? 我想知道是否可以使用任何内置的SDK函数来提高代码性能? I will be running the code on Android. 我将在Android上运行代码。

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;
 }

A running average (on integer types) can be efficiently calculated as: 可以平均计算运行平均值(整数类型):

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

To avoid having to shift all your elements through your array each time, you should use your array as a circular buffer . 为避免每次都需要在数组中移动所有元素,应将数组用作循环缓冲区

A bit late, but here's one way: 有点晚了,但这是一种方法:

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));
    }
}

Now I just made ​​myself a circular buffer (as suggested Oli Charlesworth ). 现在我只是将自己设置为循环缓冲区(如Oli Charlesworth所建议)。

And this is my implementation: 这是我的实现:

/** 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 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;
        }

I would have been using an ArrayList if I were you. 如果我是我,我会一直使用ArrayList。 Take a look at a code that does exactly the same thing as your code do. 看一看与您的代码完全相同的代码。

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;
}

And also, if you can save the variable sum for reuse, then you know how to find the new average for sure :) 而且,如果您可以保存变量总和以备重用,那么您肯定会确定如何找到新的平均值:)

There aren't better algotithm that calculate the average. 没有更好的算法来计算平均值。 The optimized code (using the same data structure) would be: 优化的代码(使用相同的数据结构)将是:

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);
}

im struggling to understand your question and your code. 我正在努力理解您的问题和代码。 i have no idea what that first loop is for at all. 我完全不知道第一个循环是干什么的。

but if your just trying to find the average your pretty much right 但是,如果您只是想找到平均值,那么您几乎是对的

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

not the fastest way but every easy to read 不是最快的方法,而是所有易于阅读的方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM