当前位置: 首页 > 知识库问答 >
问题:

Java随机化队列迭代器导致无效范围异常

岳君之
2023-03-14

我用Java实现了随机队列。虽然排队、出列和采样操作都可以正常工作,但迭代器会导致每次在shuffle方法中抛出无效范围异常。

我不明白为什么schffle()方法中的随机数生成受队列大小的约束。下面是代码:

private int N=0;
private Item[] queue;
public RandomizedQueue(){
   queue= (Item[]) new Object[8];
}                // construct an empty randomized queue
public boolean isEmpty(){
   return N==0;
}                 // is the queue empty?
public int size(){
   return N;
}// return the number of items on the queue
private void resize(int capacity){
    Item[] copy=(Item[]) new Object[capacity];
    for(int i=0;i<N;i++){
        copy[i]=queue[i];
    }
    queue=copy;
}

private class QueueIterator implements Iterator<Item>{
    int i=0;
    public QueueIterator(){
        if(N>0){
            shuffle();
        }
    }
    @Override
    public boolean hasNext() {
        return i<N;
    }

    @Override
    public Item next() {
        Item item=queue[i];
        i++;
        return item;
    }

    @Override
    public void remove() {
        throw new java.lang.UnsupportedOperationException("remove is not supported");
    }

}

public void enqueue(Item item){
    if(item==null){
        throw new java.lang.NullPointerException("can't insert null items"); 
    }

    if(N==queue.length){
        resize(2*queue.length);
    }
    queue[N++]=item;
}           // add the item
public Item dequeue(){
    if(isEmpty()){
        throw new java.util.NoSuchElementException("queue is empty");
    }
    int i=StdRandom.uniform(0, N);
    Item item=queue[i];
    exchange(i,N-1);
    N=N-1;
    queue[N]=null;
    return item;
}                    // remove and return a random item
public Item sample(){
    if(isEmpty()){
        throw new java.util.NoSuchElementException("queue is empty");
    }
    int i=StdRandom.uniform(0,N);
    return queue[i];
}                     // return (but do not remove) a random item
public Iterator<Item> iterator(){
   return new QueueIterator();
}         // return an independent iterator over items in random order
private void exchange( int i, int j){
    Item swap=queue[i];
    queue[i]=queue[j];
    queue[j]=swap;
}

private void shuffle(){
    for(int i=0;i<N;i++){
        int j=StdRandom.uniform(0, i);
        exchange(i,j);
    }
}

共有1个答案

相弘和
2023-03-14

在方法shuffle()中:

private void shuffle(){
    for(int i=0;i<N;i++){
        int j=StdRandom.uniform(0, i);
        exchange(i,j);
    }
}

在第一次迭代中,当调用StdRandom.uniform(0,0)时,它会抛出异常,因为第二个参数必须严格大于第一个参数。可能您应该更改循环的,使i的最小值为1。

从文件中:

制服

公共静态整数统一(整数a,整数b)

在[a, b)中均匀地返回一个整数。

抛出:

如果b

IllegalArgumentException-如果b-a

 类似资料:
  • 我正在Coursera学习算法课程。其中一项任务如下: 随机队列。随机化队列类似于堆栈或队列,不同之处在于移除的项是在数据结构中的项之间统一随机选择的。 我试图找到一种方法,在固定的时间内实现出列(随机删除项目)。我想到了一个主意,就是重新要求一个deque(它支持在固定时间内从前面和后面删除和添加一个项目)。我的想法如下: 在随机化队列中使用deque作为底层数据结构 加入-使用库函数生成0到1

  • 有一个非常常见且简单的任务是在两个方向上通过某个范围进行循环迭代: 上面的代码运行完美,但我花了大约一个小时试图摆脱双重检查。 有没有办法解决如果没有如果?也许是一句话?

  • 问题内容: 似乎是一个非常基本的问题。我有一个,我想对其进行迭代。一般, 绝招。但是我的要求不是迭代,而是随机地。 问题答案: 您可以在列表中使用。 请注意,这将随机排列列表,因此,如果顺序很重要,则应制作一个副本(并随机排​​列副本)。 或者,您可以创建一个包含元素的随机数组,并使用这些元素作为索引来访问中的“随机”元素。

  • 问题内容: 我正在尝试用Joda时间实现Date迭代器,但没有成功。 我需要一些可以让我整天从startDate到endDate进行迭代的东西, 您对此有任何想法吗? 问题答案: 这是一些可以帮助您入门的东西。您可能要考虑一下,是否希望它在结尾处是包容性的或排他性的,等等。 自从我用Java编写迭代器以来已经有一段时间了,所以我 希望 它是正确的。我认为这还可以… 哦,对于C#迭代器块,这就是我能

  • 如果我做:Math.random() * 4-2 这会让我得到一个范围(-2,2),2是排他性的吗?我认为这是正确的,但我很少得到正数(是的,我知道这是一个随机算法,我们必须无限随机地生成它才能感觉到,但我只是想确保) 新问题 如果我想要所有从-1到1的随机有理数,两个边界都包括在内,那么这条线是否有效:Math.random() * 2.00000000000000001 - 1; 我查了一下,

  • 我有一个用于队列的迭代器类(实现为循环数组)。我在下面附上代码。问题出在++运算符上。一旦它到达数组的末尾,它就会回到它的开始,因此迭代器会指向第一个元素。它工作得很好,但我没有办法使用这种方法实现then end()迭代器。在队列类中返回begin()和end()迭代器的函数可以在底部看到。end()迭代器应该指向队列的后部,但是当数组已满且后部等于数组的大小时,++运算符将循环返回,而不是让它