无需任何特殊数据结构即可计算移动平均线

时间:2018-09-30 18:53:26

标签: java algorithm data-structures

我最近接受了一次采访,当时我遇到一种情况,我需要计算给定时间段内的移动平均线。我提出了以下解决方案,但面试官说他希望我在没有任何特殊数据结构的情况下完成此操作,因为DS会占用一些空间?没有任何数据结构还有其他更好的方法吗?

public class MovingAverage {
  private final Queue<BigDecimal> window = new ArrayDeque<>();
  private final int period;
  private BigDecimal sum = BigDecimal.ZERO;

  public MovingAverage(int period) {
    this.period = period;
  }

  public void add(BigDecimal num) {
    sum = sum.add(num);
    window.add(num);
    if (window.size() > period) {
      sum = sum.subtract(window.remove());
    }
  }

  public BigDecimal getAverage() {
    if (window.isEmpty())
      return BigDecimal.ZERO;
    BigDecimal divisor = BigDecimal.valueOf(window.size());
    return sum.divide(divisor, 2, RoundingMode.HALF_UP);
  }
}

1 个答案:

答案 0 :(得分:1)

固定长度的数组是否算作“特殊数据结构”?如果没有,您可以执行以下操作:

public class MovingAverage {
  private final BigDecimal[] window;
  private final int period;
  private int size;
  private int idx;
  private BigDecimal sum = BigDecimal.ZERO;

  public MovingAverage(int period) {
    this.period = period;
    window = new BigDecimal[period];
  }

  public void add(BigDecimal num) {    
    if(size < period)
      size += 1;
    else 
      sum = sum.subtract(window[idx]);

    sum = sum.add(num);
    window[idx++] = num;
    if(idx == period) idx = 0;
  }

  public BigDecimal getAverage() {
    if (size == 0)
      return BigDecimal.ZERO;
    BigDecimal divisor = BigDecimal.valueOf(size);
    return sum.divide(divisor, 2, RoundingMode.HALF_UP);
  }  
}