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