找不到基于数组的双端队列的问题,但出现越界异常
多年来我一直试图解决这个问题,但没有成功。我想我的代码一定有几个我看不到的问题。我之前用稍微复杂一点的方式实现了这个,并以更简单的形式编写它来帮助我下面一年级正在挣扎的朋友,但我最终让自己陷入了困境!
代码如下:
public class ArrayBasedDeque<EltType> implements Deque<EltType> {
private final int CAPACITY = 10;
private int capacity;
private int end;
private EltType deque[];
public ArrayBasedDeque() {
this.capacity = CAPACITY;
deque = (EltType[]) (new Object[capacity]);
}
public EltType first() {
return deque[0];
}
public EltType last() {
return deque[end];
}
public boolean isEmpty() {
return end == 0;
}
public int size() {
return deque.length;
}
public boolean isFull() {
int curSize = size();
return curSize >= capacity;
}
public void insertFirst(EltType first) {
if(!isEmpty()) {
EltType[] tempArray;
tempArray = (EltType[]) new Object[capacity+1];
for (int i=0;i<deque.length;i++) {
tempArray[i+1] = deque[i];
}
deque = tempArray;
}
deque[0] = first;
end++;
}
public void insertLast(EltType last) {
if (isFull()){
EltType[] tempArray;
tempArray = (EltType[]) new Object[CAPACITY+1];
for (int i=0;i<deque.length;i++) {
tempArray[i] = deque[i];
}
}
deque[end] = last;
end++;
}
public EltType removeFirst() {
EltType[] tempArray;
EltType returned = deque[0];
tempArray = (EltType[]) new Object[capacity];
for (int i=1;i<capacity;i++) {
tempArray[i-1] = deque[i];
}
deque = tempArray;
end--;
return returned;
}
public EltType removeLast() {
EltType[] tempArray;
System.out.println(end);
EltType returned = deque[end];
tempArray = (EltType[]) new Object[capacity];
for (int i=0;i<deque.length;i++) {
tempArray[i] = deque[i];
}
deque = tempArray;
return returned;
}
}
问题是,当我调用
abd.insertFirst( 3 );
abd.insertFirst( 3 );
abd.insertFirst( 3 );
它时,它返回一个错误。
java.lang.ArrayIndexOutOfBoundsException: 11
at ArrayBasedDeque.insertFirst(ArrayBasedDeque.java:37)
at TestABD.main(TestABD.java:7)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)
insertLast 方法也是如此。我无法弄清楚,希望 stackOverflow 的仔细观察可以帮助我。多谢 !
I have been trying to figure this out for an age, but to no avail. I think I must have several problems with my code that I just can't see. I have implemented this using a slightly more complex way before, and was writing it in a simpler form to help a friend in the year below me who is struggling, but I've just ended up getting myself in a muddle!
The code is as follows :
public class ArrayBasedDeque<EltType> implements Deque<EltType> {
private final int CAPACITY = 10;
private int capacity;
private int end;
private EltType deque[];
public ArrayBasedDeque() {
this.capacity = CAPACITY;
deque = (EltType[]) (new Object[capacity]);
}
public EltType first() {
return deque[0];
}
public EltType last() {
return deque[end];
}
public boolean isEmpty() {
return end == 0;
}
public int size() {
return deque.length;
}
public boolean isFull() {
int curSize = size();
return curSize >= capacity;
}
public void insertFirst(EltType first) {
if(!isEmpty()) {
EltType[] tempArray;
tempArray = (EltType[]) new Object[capacity+1];
for (int i=0;i<deque.length;i++) {
tempArray[i+1] = deque[i];
}
deque = tempArray;
}
deque[0] = first;
end++;
}
public void insertLast(EltType last) {
if (isFull()){
EltType[] tempArray;
tempArray = (EltType[]) new Object[CAPACITY+1];
for (int i=0;i<deque.length;i++) {
tempArray[i] = deque[i];
}
}
deque[end] = last;
end++;
}
public EltType removeFirst() {
EltType[] tempArray;
EltType returned = deque[0];
tempArray = (EltType[]) new Object[capacity];
for (int i=1;i<capacity;i++) {
tempArray[i-1] = deque[i];
}
deque = tempArray;
end--;
return returned;
}
public EltType removeLast() {
EltType[] tempArray;
System.out.println(end);
EltType returned = deque[end];
tempArray = (EltType[]) new Object[capacity];
for (int i=0;i<deque.length;i++) {
tempArray[i] = deque[i];
}
deque = tempArray;
return returned;
}
}
The problem is that when I call
abd.insertFirst( 3 );
abd.insertFirst( 3 );
abd.insertFirst( 3 );
this, it returns an error.
java.lang.ArrayIndexOutOfBoundsException: 11
at ArrayBasedDeque.insertFirst(ArrayBasedDeque.java:37)
at TestABD.main(TestABD.java:7)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)
the same is true for the insertLast method. I can't figure it out, and was hoping the scrutinizing gaze of stackOverflow could help me. Thanks a lot !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
第一次方法调用后,
deque
是一个长度为 11 的数组 (deque
==tempArray
==new Object[capacity+1 ]
==new Object[11]
下次调用该方法时,为capacity+1
= 分配tempArray
。 =11
个槽,但将 for 循环从0
遍历到deque.length
,即0
到>10
在第二个方法调用上,循环的最后一次结束是:它超过了
tempArray
的末尾,它只有11
槽 (< code>[0] 到[10]
)。简单的解决方法是让 for 循环从
0
到capacity
。 > 而不是从0
到deque.length
,但我不确定这是否实现了您想要的实际行为。另一种方法是分配tempArray = new Object。 [deque.length+1]
,但是capacity
并不真正意味着容量,它仍然可能无法从概念上反映您认为在这种情况下的“正确”行为。After the first method call,
deque
is an array of length 11 (deque
==tempArray
==new Object[capacity+1]
==new Object[11]
. The next time the method is called, you allocatetempArray
forcapacity+1
==11
slots, but traverse the for-loop from0
todeque.length
which is0
to10
on the second method call. The last pass of the loop ends up being:which is past the end of
tempArray
which only has11
slots ([0]
to[10]
).The naive fix is to have the for-loop go from
0
tocapacity
instead of from0
todeque.length
, but I'm unsure if this implements the actual behavior you want. Another approach is to allocatetempArray = new Object[deque.length+1]
, but thencapacity
doesn't really mean capacity and it still may not reflect conceptually what you think is the "correct" behavior in that situation.我在 Java 方面没有太多经验,所以我可能在这里有所偏差,但是......当您调用 InsertFirst 时,尚未将任何值设置为容量。所以它默认为 0 或垃圾。不管怎样,当你打电话时
tempArray = (EltType[]) new Object[容量+1];
容量要么是 1,要么是……某个“随机”数字。这就是为什么会出现越界。我猜你是想使用容量?
I don't have much experience in Java, so I could be off base here but...when you call InsertFirst, no values been set to capacity yet. So it defaults to either 0, or junk. Either way, when you call
tempArray = (EltType[]) new Object[capacity+1];
the capacity will either be 1 or...some 'random' number. Hence why are getting outOfBounds. I'm guessing you meant to use CAPACITY?
这是该特定错误的答案。您没有更新实例变量
capacity
,因此每次调用insertFirst
时,临时数组实际上并没有增长。所以代码应该如下所示:尽管如此,总体类还远远不正确。
Here is the answer to that particular bug. You aren't updating the instance variable
capacity
so each time you callinsertFirst
the temp array array isn't actually growing. So the code should look like:Still, the overal class is far from correct.