我正在尝试使用一种算法来跟踪循环缓冲区中数字的平均值,假设数字在缓冲区接近容量时被覆盖。
e.g. size = 4
[1,2,7,3] => avg = 13/4 = 3.25
add(5)
[5,2,7,3] => avg = 17/4 = 4.25
这是我目前的做法。
class CircularBuffer {
int[] buffer;
int head;
int tail;
int sum;
public CircularBuffer(int n) {
tail = 0;
head = 0;
buffer = new int[n];
}
void addNumber(int number) {
if (head == tail - 1) {
sum -= buffer[tail - 1];
} else if (head != tail - 1) {
buffer[head++]= number;
sum += number;
}
head = head % buffer.length;
}
double avg() {
if (head > vtail) {
return sum / (head - tail + 1);
} else {
return sum / buffer.length;
}
}
public static void main(String[] args) {
CircularBuffer buf = new CircularBuffer(3);
buf.addNumber(1);
buf.addNumber(2);
buf.addNumber(3);
buf.addNumber(4);
System.out.println("Avg"+ buf.avg());
}
什么不起作用:目前返回5而不是3。
答案 0 :(得分:1)
你真的不需要尾巴,你只需要知道你是否达到缓冲区的长度,所以代码看起来像这样:
class CircularBuffer {
int tail = 0;
int head = 0;
int[] buffer;
int sum = 0;
public CircularBuffer(int n) {
buffer = new int[n];
}
void addNumber(int number) {
sum -= buffer[head];
sum += number;
buffer[head++] = number;
head = head % buffer.length;
if (tail <= buffer.length) {
tail++;
}
}
double avg() {
if (head == tail) {
return (double) sum / (double) head;
} else {
return (double) sum / (double) buffer.length;
}
}
public static void main(String[] args) {
CircularBuffer buf = new CircularBuffer(3);
buf.addNumber(1);
buf.addNumber(2);
buf.addNumber(3);
buf.addNumber(4);
System.out.println("Avg" + buf.avg());
}
}
由于buffer = new int[n];
用零填充缓冲区,因此在方法addnumber中不需要任何if / else,只需减去前一个值并添加当前值即可。希望很清楚。
答案 1 :(得分:0)
为什么你只能将平均代码与添加代码分开?
然后你只需要遍历数组,求它并将其除以长度。
答案 2 :(得分:0)
addNumber
方法似乎无法正常工作。
首先,如果你想测试你的缓冲区是否已满,你还需要考虑head == tail -1
的情况而不是简单的head==length-1 && tail==0
。
其次,如果缓冲区已满,则需要增加头部和尾部。您可以通过head = (head+1)%length
代替简单head++
,因为head
可能是length-1
。尾巴也一样。此外,在这种情况下,您忘记将数字添加到总和中,以及实际将数字插入到后备数组中。
答案 3 :(得分:0)
我稍微修改了你的代码。这是主要方法,基于您在问题中输入的内容。
public static void main(String[] args) {
CircularBuffer buf = new CircularBuffer(4);
buf.addNumber(1);
buf.addNumber(2);
buf.addNumber(7);
buf.addNumber(3);
System.out.println("Avg " + buf.avg());
buf.addNumber(5);
System.out.println("Avg " + buf.avg());
}
这是我运行代码时的结果。
Avg 3.25
Avg 4.25
这是我为了让你的代码首先编译,然后正确执行而改变了。
我添加了一个类声明,并将所有变量都设为类变量。
不需要头部变量。它总是处于零位。
我添加了一个布尔值,让我知道循环缓冲区中的值是否被覆盖。
我在构造函数中初始化了sum和boolean变量bufferFull。
我重写了addNumber方法,以便总和总是包含正确的值。
由于sum总是具有正确的值,因此avg方法只计算平均值。
我格式化了Java代码,以便其他人更容易阅读。
这是经过修改的代码。
package com.ggl.testing;
public class CircularBuffer {
private boolean bufferFull;
private int tail;
private int sum;
private int[] buffer;
public CircularBuffer(int n) {
this.bufferFull = false;
this.tail = 0;
this.sum = 0;
this.buffer = new int[n];
}
public void addNumber(int number) {
sum += number;
if (bufferFull) {
sum -= buffer[tail];
}
buffer[tail] = number;
tail++;
if (tail >= buffer.length) {
tail = tail % buffer.length;
bufferFull = true;
}
}
public double avg() {
int length = tail;
if (bufferFull) {
length = buffer.length;
}
return (double) sum / length;
}
public static void main(String[] args) {
CircularBuffer buf = new CircularBuffer(4);
buf.addNumber(1);
buf.addNumber(2);
buf.addNumber(7);
buf.addNumber(3);
System.out.println("Avg " + buf.avg());
buf.addNumber(5);
System.out.println("Avg " + buf.avg());
}
}
我希望您了解我的所作所为,并将这些原则应用于您的下一个任务。