[英]Algorithm — Finding the average of numbers in a circular buffer?
我試圖考慮一種算法來跟蹤循環緩沖區中數字的平均值,假設隨着緩沖區接近容量,數字將被覆蓋。
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。
您實際上不需要尾巴,只需要知道是否達到緩沖區的長度即可,因此代碼如下所示:
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,只需減去之前的值並添加當前值即可。 希望清楚。
為什么只將平均代碼與添加代碼分開?
然后,您只需要遍歷數組,將其求和並除以長度即可。
addNumber
方法似乎無法正常工作。
首先,如果要測試緩沖區是否已滿,還需要考慮以下情況: head==length-1 && tail==0
,而不是簡單的head == tail -1
。
其次,如果緩沖區已滿,則需要同時增加頭和尾。 而且您可以使用head = (head+1)%length
來代替簡單的head++
,因為head
可能是length-1
。 尾巴也一樣。 另外,在這種情況下,您忘記將數字添加到總和中,以及實際上將數字插入到支持數組中。
我對您的代碼做了一些修改。 這是主要方法,基於您在問題中鍵入的內容。
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
這是我所做的更改,以使您的代碼先進行編譯,然后正確執行。
我添加了一個類聲明,並使所有變量成為類變量。
不需要head變量。 總是零位。
我添加了一個布爾值,讓我知道循環緩沖區中的值何時被覆蓋。
我在構造函數中初始化了sum和布爾變量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());
}
}
希望您能理解我的所作所為,並可以將這些原則應用於下一個任務。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.