2017-03-07 82 views
-2

我試圖實現一個記住最後N個元素的環。它添加元素並正確更改指針。 get()方法必須返回添加到環中的最新元素。我試圖用筆和紙在get方法中找到邏輯,最終,我設法做到了。但是,當我運行我的代碼時,它似乎並不如此。我在這裏先向您的幫助表示感謝。Java Ring實現

[1] [2] [3] [4] [5] < - 在以下的例子中,得到(0)必須返回5,並獲得(1) - 4

迭代與打印

[1] [2] [3] [4] [5]

使用GET方法 - 獲取(0),得到(1)....

[1] [5] [ 4] [3] [2] - 這裏[1]必須在[2]的右側

import java.util.AbstractCollection; 
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Iterator; 

public class CircularArrayRing<E> extends AbstractCollection<E> implements Ring<E> 
{ 

    private int elements; 
    private int front; 
    private E[] ring; 

    @SuppressWarnings("unchecked") 
    public CircularArrayRing() 
    { 
     ring = (E[]) new Object[10]; 
     front = 0; 
    } 

    @SuppressWarnings("unchecked") 
    public CircularArrayRing(int size) 
    { 
     ring = (E[]) new Object[size]; 
     front = 0; 
    } 

    @Override 
    public boolean add(E e) 
    { 

     ring[front] = e; 
     front++; 

     if(front == ring.length) 
     { 
      front = 0; 
     } 

     if(elements < ring.length) 
     { 
      elements++; 
     } 

     return false; 
    } 

    @Override 
    public Iterator<E> iterator() 
    { 

     return null; 
    } 

    @Override 
    public int size() 
    { 
     return elements; 
    } 

    @Override 
    public E get(int index) throws IndexOutOfBoundsException 
    { 
     if(index > elements - 1 || index > ring.length - 1) 
     {  
      throw new IndexOutOfBoundsException(); 
     } 
     else 
     {  
      if (index > front) 
      { 
       return ring[ring.length + front -index]; 
      } 
      else 
      { 
       return ring[front - index]; 
      } 

     } 

    } 

} 
+1

調試並沒有幫助,請參閱:什麼是調試器和它如何可以幫助我診斷問題?](http://stackoverflow.com/q/25385173/5221149) – Andreas

回答

0

數組索引處理有一些錯誤。

例如,如果我們看一下基本情況,只需1個元素,調用get(0)的邏輯是:

front - index = 1 - 0 = 1 ->ArrayIndexOutOfBounds

從這我們可以看到,front應減少1以達到正確的指數。

進一步的測試將顯示相同的修補程序也應該應用於if的另一個分支,並且條件本身應該是>=而不是>

get正確的代碼將被:

if (index >= front) { 
    return ring[ring.length + front - 1 - index]; 
} 
else { 
    return ring[front - 1 - index]; 
} 
+0

「return ring [ring.length + front - 1 - index]」無法訪問。當初始化給定大小的對象(比如說3)時,當添加最後一個元素時,它會拋出ArrayIndexOutOfBoundsException異常。 他幾乎所有的實現都是錯誤的。 – LppEdd

+0

@LppEdd它不可及,也似乎一切正常,我有任何例子顯示相反? –

+0

嘗試用3個元素初始化集合。添加三個元素,然後得到0,1,2 – LppEdd

0

所以,在你的實現看起來稍微好一些後,我試着重寫它。
無需初始化sizeeffectiveSize,因爲它們的默認值是0作爲類成員。
我認爲這仍然是你想要的。

public class CircularArrayRing<E> extends AbstractCollection<E> 
{ 
    private final E[] ring; 
    private int size; 
    private int effectiveSize; 

    @SuppressWarnings("unchecked") 
    public CircularArrayRing() { 
     ring = (E[]) new Object[10]; 
    } 

    @SuppressWarnings("unchecked") 
    public CircularArrayRing(final int size) { 
     ring = (E[]) new Object[size]; 
    } 

    @Override 
    public boolean add(final E e) { 
     if (effectiveSize < ring.length) { 
     effectiveSize++; 
     } 

     if (size >= ring.length) { 
     size = 0; 
     } 

     ring[size++] = e; 
     return true; 
    } 

    @Override 
    public Iterator<E> iterator() { 
     return null; 
    } 

    @Override 
    public int size() { 
     return effectiveSize; 
    } 

    public E get(final int index) throws IndexOutOfBoundsException { 
     if (index < 0 || index > effectiveSize - 1) { 
     throw new IndexOutOfBoundsException(); 
     } 

     return ring[effectiveSize - index - 1]; 
    } 
} 
+0

我仍然不知道如何發生這種情況如果我改變這行代碼來匹配你的我得到ArrayIndexOutOfBounds –

+0

發佈你如何使用這門課。 – LppEdd

+0

@RadoslavTodorov查看最新的答案。 – LppEdd