今天突然发现Autograder可以用,于是把项目1、2发上去评了评分,其他的都没什么错。就是pro1a里的ArrayDeque一直有bug,发现是Resize方法的问题,怎么也解决不了bug。然后就经历了和每次刷leetcode一样的事,看了答案发现自己简直是傻子。
ArrayDeque Resizing
我第一次的想法是:将原数组中的值直接拷贝到新的数组的i——i-1+size去,然后nextFirst和nextLast指向两端。错误在于这样nextFirst和nextLast的位置就丢失了。但是其实已经很接近正确答案了。
第二次,我想到数组需要扩充的时候,nextFirst = minusOne(nextLast)是一定成立的。所以,将nextFirst到最后拷贝到新数组的最后,将0到nextLast拷贝到新数组的0开头。需要扩充数组的时候这种做法完全没问题,但是当考虑usage需要减小数组的时候就有bug。
首先是有可能nextFisrt < nextLast(因为减小数组时数组不是满的)。这问题不大,加个判断就行。
if (nextFirst == minusOne(nextLast) || nextFirst > nextLast) { //数据在数组两端
System.arraycopy(items, 0, t, 0, nextLast);
int backLen = items.length - addOne(nextFirst);
System.arraycopy(items, addOne(nextFirst), t, capacity - backLen, backLen);
nextFirst = capacity - backLen - 1;
} else { //数据在数组中间
System.arraycopy(items, addOne(nextFirst), t, 0, size);
nextFirst = capacity - 1;
nextLast = size;
}
最后搞成了这个样子,就实在搞不下去了,减小size的时候总会在边界出bug。和刷leetcode很多题的感觉一样,如果开始思路没对,就会一直加条件语句,但是穷尽不了所有条件。
实际上,这样就可以了
private void resize(int capacity) {
T[] t = (T[]) new Object[capacity];
int oldIndex = plusOne(nextFirst);
for (int newIndex = 0; newIndex < size; newIndex++) {
t[newIndex] = items[oldIndex];
oldIndex = plusOne(oldIndex);
}
nextFirst = capacity - 1;
nextLast = size;
items = t;
}
思想就是将原数组的数据按顺序拷贝到新数组的0位,就这么简单。
哎太笨了。