在混洗数组上嵌套的独立迭代器

时间:2015-10-11 15:45:29

标签: java arrays random iterator

我在java中使用调整大小数组实现了一个可迭代的随机队列。当我尝试以不同的随机顺序在相同的数据上有两个独立的迭代器时,问题出现了。 main创建一个包含5个整数(0-4)的队列,然后创建一个嵌套的while循环,以独立的随机顺序迭代数据。内循环在每次迭代中都能正常工作(即以5个不同的随机顺序打印出0-4)。问题是当创建内部迭代器时,它会覆盖第一个迭代器中的数据,但索引变量i除外。因此,在外部迭代器上调用next()会返回内部迭代器中索引处的值。

实施例: 如果内部迭代器在第一次通过后返回1 3 2 0 4。对外迭代器的next()调用将返回1。 如果内部迭代器在第3次通过后返回3 0 4 2 1。对外迭代器的next()调用将返回4。 如果内部迭代器在第5次通过后返回4 1 0 3 2。对外迭代器的next()调用将返回2.

如何使迭代器彼此独立?

...
// return an independent iterator over items in random order
public Iterator<Item> iterator() {
    if (N == 0) return null;
    return new RandomizedQueueIterator();
}

private class RandomizedQueueIterator implements Iterator<Item> {
    private int i;
    private Item[] array;
    public RandomizedQueueIterator() {
        array = a;
        StdRandom.shuffle(array, 0, N-1);
        i = 0;
    }
    public boolean hasNext() {
        return i < N;
    }
    public void remove() {
        throw new UnsupportedOperationException("Remove not supported");
    }
    public Item next() {
        if (!hasNext()) throw new NoSuchElementException("No more items");
        return array[i++];
    }
}
...
// unit testing
public static void main(String[] args) {
    RandomizedQueue rq = new RandomizedQueue();
    int count = 0;
    for (int i = 0; i < 5; i++)
        rq.enqueue(i);
    Iterator iterator = rq.iterator();
    while (iterator.hasNext()) {
        Iterator innerIt = rq.iterator();
        while (innerIt.hasNext()) {
            System.out.print(innerIt.next() + " ");
        }
        System.out.println();
        System.out.println(iterator.next());
    }
}

shuffle方法可以很好地实现Knuth Shuffle算法。

1 个答案:

答案 0 :(得分:0)

您可能需要在迭代器构造函数中创建数组的副本。 请参阅:http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#copyOf(T[],%20int)

    array = Arrays.copyOf(a, a.length);