2016-03-25 6 views
-1

私はJavaを初めて使用しています。私はカスタムPriorityQueueのためのメソッドを作成しようとしています。これは、2つのPriorityQueuesをマージする配列を使用する必要があります。Javaコンパイラは、何の理由もなくjava.lang.ArrayIndexOutOfBoundsExceptionを呼び出します。

問題は、自分のコードにエラーがないうちに、EclipseのJavaコンパイラがmainでそのメソッドを呼び出すたびにjava.lang.ArrayIndexOutOfBoundsExceptionを呼び出してしまうことです。

マージメソッドについて: 基本的に2つの配列の要素を1つの配列にマージする方法です。そして、それはextractMax法を用いて、二番目の配列のすべての要素を消去します:

これまでのところ、私のコードはこれです:私は日食でこれを実行するたびに

//Custom Priority Queue 
class PriorityQueue { 
    private int capacity; 
    private int queue[]; 
    private int i; 

    public PriorityQueue() { 
     capacity = 100; 
     queue = new int[100]; 
     i = 0; 
    } 

    public PriorityQueue(int size) { 
     capacity = size; 
     queue = new int[size]; 
     i = 0; 
    } 

    protected void quickSort(int left, int right) { 
     int i = left, j = right; 
     int pivot = queue[(left + right)/2]; 

     while (i <= j) { 
      while (queue[i] > pivot) 
       i++; 
      while (queue[j] < pivot) 
       j--; 
      if (i <= j) { 
       int temp = queue[i]; 
       queue[i] = queue[j]; 
       queue[j] = temp; 
       i++; 
       j--; 
      } 
     } 
     if (left < j) 
      quickSort(left, j); 
     if (i < right) 
      quickSort(i, right); 
    } 

    public boolean insert(int number) { 
     if(i < capacity) { 
      queue[i] = number; 
      quickSort(0, i++); 
      return true; 
     } 
     return false; 
    } 

    public int extractMax() { 
     if(i == 0) 
      return -1; 
     else { 
      int tempQueue[] = new int[i-1]; 
      int temp = queue[0]; 

      for(int j=0; j<i-1; j++) 
       tempQueue[j] = queue[j+1]; 
      queue = tempQueue; 
      i--; 
      return temp; 
     } 
    } 

    public boolean merge(PriorityQueue myPriorityQueue) { 
     if(i + myPriorityQueue.i < capacity) { 
      for(int j=0; j<myPriorityQueue.i; j++) 
       queue[i++] = myPriorityQueue.extractMax(); 
      quickSort(0, i-1); 
      return true; 
     }  
     return false; 
    } 

//Test Class 
class PriorityQueueTest 
{ 
    public static void main(String args[]) 
    { 
     PriorityQueue PQ1 = new PriorityQueue(); 
     PriorityQueue PQ2 = new PriorityQueue(); 

     PQ1.insert(1); 
     PQ1.insert(3); 
     PQ1.insert(5); 
     PQ2.insert(2); 
     PQ2.insert(4); 
     PQ2.insert(6); 

     PQ1.merge(PQ2);  
    } 
} 

は、だから私は得る:

java.lang.ArrayIndexOutOfBoundsException: 2 
at PriorityQueue.merge(PriorityQueue.java:89) 
at PriorityQueueTest.main(PriorityQueueTest.java:22) 

私はそれがなぜそれをするのか理解しようとしましたが、意味がありません。 この例では、2つのPriorityQueuesの長さがPriorityQueue1の容量を超えません。 PriorityQueues要素にアクセスしようとすると何か問題があるはずです。

ありがとうございました、ありがとうございました。

+1

89行目はどれですか? –

+0

sry、それは実際に88行目で、88行目は: キュー[i ++] = myPriorityQueue.extractMax(); – user6115152

+1

コードを1行ずつデバッグしようとしましたか? –

答えて

0

問題はここにある:

具体的
for(int j=0; j<myPriorityQueue.i; j++) 
      Queue[i++] = myPriorityQueue.extractMax(); 
     QuickSort(0, i-1); 
     return true; 

、あなたがQueue[i++]iをインクリメントしているので - j常にmyPriorityQueue.iより小さくなります - ローカルのものではなく、それはあなたのクラス変数iです。したがって、このループはjcapacityを超えるまで常に実行され、Queue[]要素の長さを超えてアクセスしようとすると、ArrayIndexOutOfBounds例外がスローされます。このようなループでは、通常、ループ内の配列の要素にアクセスするためにjを使用します。

for(int j=0; j<myPriorityQueue.i; j++) 
      Queue[j] = myPriorityQueue.extractMax(); 
     QuickSort(0, i-1); 

この方法ではiまでQueue[]、およびjでのみアクセス要素が自動的に各反復の最後にインクリメントされますループの

物事ではなく、そのようなijのような単一の文字があるqueuedまたはstored、のようなより説明的なもので、キューにあるどのように多くのものを追跡するためにあなたのクラス変数の一つとしてiを使用するように選択することによって、より混乱作られています頻繁にループで使用されます。 QuickSortループで実際にiを使用しました。クラスには既に変数iが含まれています。ループカウンター外の変数にわかりにくい名前を使用することは悪い習慣であり、コードを理解しにくくします。

+0

変数 "i"を変更すると、 "myPriorityQueue.i"という変数も変更されます...そうです、ありがとう、たくさんの人!!!! – user6115152

関連する問題