ArrayDeque - Resizing

今天突然发现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位,就这么简单。
哎太笨了。

发布了20 篇原创文章 · 获赞 0 · 访问量 170

猜你喜欢

转载自blog.csdn.net/fourier_transformer/article/details/105253089