我是Java新手。我正在尝试为自定义PriorityQueue创建一个方法,该方法必须使用一个Array,它合并2个PriorityQueues。
问题在于,虽然我的代码中没有错误,但只要我在main中调用该方法,Eclipse中的Java编译器就会调用java.lang.ArrayIndexOutOfBoundsException。
关于合并方法: 它基本上是一个方法,它采用2个数组的元素并将它们合并为一个数组。然后使用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);
}
}
所以每当我在eclipse中运行时,我得到:
java.lang.ArrayIndexOutOfBoundsException: 2
at PriorityQueue.merge(PriorityQueue.java:89)
at PriorityQueueTest.main(PriorityQueueTest.java:22)
我试图找出它为什么这样做,但这没有任何意义。 在此示例中,2 PriorityQueues的长度不超过PriorityQueue1的容量。当我尝试访问PriorityQueues元素时,一定有问题。
谢谢,感谢任何帮助。
答案 0 :(得分:0)
问题在于:
for(int j=0; j<myPriorityQueue.i; j++)
Queue[i++] = myPriorityQueue.extractMax();
QuickSort(0, i-1);
return true;
更具体地说,由于您使用i
递增Queue[i++]
- 这是您的类变量i
,而不是本地变量j
将始终小于{{} 1}}。因此,此循环将始终运行,直到myPriorityQueue.i
超过j
并在您尝试访问大于其长度的capacity
元素时抛出ArrayIndexOutOfBounds
异常。在这样的循环中,您通常会使用Queue[]
来访问循环内数组中的元素:
j
这种方式只会访问for(int j=0; j<myPriorityQueue.i; j++)
Queue[j] = myPriorityQueue.extractMax();
QuickSort(0, i-1);
中的元素,最多Queue[]
,而i
会在循环的每次迭代结束时自动递增。
您选择使用j
作为类变量之一来跟踪队列中有多少内容,而不是像i
或{{1}这样更具描述性的内容,让事情变得更加混乱},当queued
和stored
等单个字母经常用于循环时;当你的类已经有一个变量i
时,你实际上在QuickSort循环中使用了j
。对循环计数器之外的变量使用非描述性名称是不好的做法,使代码更难理解。