2017-03-07 18 views
-2

最後のN個の要素を覚えているリングを実装しようとしています。要素を追加してポインタを正しく変更します。 get()メソッドは、リングに追加された最新の要素を返す必要があります。私はペンと紙でgetメソッドのロジックを見つけようとしましたが、結局それをやり遂げました。しかし、私は私のコードを実行すると、そう思わない。事前に助けてくれてありがとう。Javaリングの実装

[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

:[Aは何ですか?デバッガとどのように私が問題を診断するのを助けることができますか?(http://stackoverflow.com/q/25385173/5221149) – Andreas

答えて

0

配列インデックスの処理にはいくつかの間違いがあります。例えば

私達はちょうど1要素と基本ケースを見れば、get(0)を呼び出すロジックは次のとおりです。

front - index = 1 - 私たちはfrontがあるべきことがわかります。このことから0 = 1 ->ArrayIndexOutOfBounds

正しいインデックスに達するために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つの要素でコレクションを初期化しようとします。 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