Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 不使用任何特殊数据结构计算移动平均数_Java_Algorithm_Data Structures - Fatal编程技术网

Java 不使用任何特殊数据结构计算移动平均数

Java 不使用任何特殊数据结构计算移动平均数,java,algorithm,data-structures,Java,Algorithm,Data Structures,我最近接受了一次采访,在采访中,我遇到了一种情况,在这种情况下,我需要计算给定时段的移动平均线。我提出了下面的解决方案,但面试官说他希望我在没有任何特殊数据结构的情况下这样做,因为DS会占用一些空间?在没有任何数据结构的情况下,还有其他更好的方法吗 public class MovingAverage { private final Queue<BigDecimal> window = new ArrayDeque<>(); private final int p

我最近接受了一次采访,在采访中,我遇到了一种情况,在这种情况下,我需要计算给定时段的移动平均线。我提出了下面的解决方案,但面试官说他希望我在没有任何特殊数据结构的情况下这样做,因为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);
  }
}
公共类移动平均值{
private final Queue window=new ArrayDeque();
私人最后整修期;
私有BigDecimal和=BigDecimal.0;
公共移动平均值(国际期间){
这个周期=周期;
}
公共void add(BigDecimal num){
sum=sum.add(num);
window.add(num);
if(window.size()>period){
sum=sum.subtract(window.remove());
}
}
公共BigDecimal getAverage(){
if(window.isEmpty())
返回BigDecimal.ZERO;
BigDecimal除数=BigDecimal.valueOf(window.size());
返回和除法(除数,2,取整模式,向上减半);
}
}

固定长度数组是否算作“特殊数据结构”?如果没有,您可以这样做:

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);
  }  
}
公共类移动平均值{
私有最终BigDecimal[]窗口;
私人最后整修期;
私有整数大小;
私有int idx;
私有BigDecimal和=BigDecimal.0;
公共移动平均值(国际期间){
这个周期=周期;
窗口=新的大十进制[句点];
}
公共void add(BigDecimal num){
如果(大小<周期)
大小+=1;
其他的
总和=总和减去(窗口[idx]);
sum=sum.add(num);
窗口[idx++]=num;
如果(idx==周期)idx=0;
}
公共BigDecimal getAverage(){
如果(大小==0)
返回BigDecimal.ZERO;
BigDecimal除数=BigDecimal.valueOf(大小);
返回和除法(除数,2,取整模式,向上减半);
}  
}

这里有很多解决方案,也许你可以找到;不,你需要以某种方式存储数据。他指的是不用排队就能完成吗?“没有任何特殊的数据结构”可能意味着面试官希望你们使用数组
ArrayDeque
只是数组的包装器,因此它使用的额外内存非常少,特别是与数组中的所有
BigDecimal
对象相比,因此与普通数组相比,
ArrayDeque
使用的额外内存非常小,不需要考虑。如果面试官坚持要考虑这个问题,告诉他们在这个问题上浪费时间是错误的但是,可以通过使用
new ArrayDeque(period+1)
@RamanMishra来管理
ArrayDeque
中的数组大小,使其不会过大,因为
ArrayDeque
为您处理队列方面的问题,所以您不必编写保留2个索引值的所有逻辑,我认为你做得完全正确。您为作业选择了正确的数据结构,并且(据我所知)实现了正确的解决方案。也许面试官希望你提出一个论点,为什么你的解决方案是最好的。我们必须在这里使用BigDecimal吗?使用double[]而不是BigDecimal,这样效率更高,怎么样?@john no如果您确信所有内容都可以放入一个double@john如果使用双精度,则会累积舍入误差,因为减去窗口末尾的数字可能无法完全取消窗口开头的加法。这需要一些额外的工作来修复。我不确定BigDecimal是否也有同样的问题。