简体   繁体   中英

Im having a problem with my iterator reading more than 3 items

So I have looked over this code for the past couple hours and cannot find the bug. Subset takes in an array for 3 String characters and it will read through and print them out fine, but if I add more than three elements it kicks out an arrayoutofbounds exception and I cannot figure out why. I can manually add them in one by one and it will work but thats not the way that the program was designed to work. Im sure the solution is simple but I cannot find it. Any ideas? Thanks so much.

package a02;

import java.util.Iterator;

import edu.princeton.cs.algs4.StdRandom;


/**
 * 
 * @author Danny
 *
 * @param <Item>
 */
public class RandomizedQueue<Item> implements Iterable<Item> {
private Item[] queue  ;
private int size;
/**
 * Constructs an empty randomized queue.
 */
public RandomizedQueue() {
    queue = (Item[])new Object[1];
    size=0;
}
/**
 * parameterized constructor for the Iterator class.
 * @param array
 */
private RandomizedQueue(Item[] array)
{
    int count = 0;
    queue = array;
    while(queue[count]!=null)
        count++;
    queue = (Item[])new Object[array.length];
    for(int i=0;i<count;i++)
        queue[i]=array[i];
    size=count;
}

private Item[] getArray() {
    return queue;
}

/**
 * Checks to see if the queue is empty.
 * @return
 */
public boolean isEmpty() {                
    return size<=0;
}

/**
 * Returns the number of items in the queue.
 * @return
 */
public int size() {                  
    return size;
}

/**
 * Adds an item.
 * @param item
 */
public void enqueue(Item item) {    
     if (item == null) 
         throw new java.lang.NullPointerException();
    if (size == queue.length)
        resize(2*queue.length);
    queue[size]= item;
    size++;
}

/**
 * Deletes and returns a random item
 * @return
 */
public Item dequeue() {      
    if (isEmpty())
        throw new java.util.NoSuchElementException();
    int index = StdRandom.uniform(size);
    Item item = queue[index];
    if(index == size-1)
        queue[index] = null;
    else {
        queue[index] = queue[size-1];
        queue[size-1]=null;
    }
    size--;
    if(size<=queue.length/4)
        resize(queue.length/2);
    return item;
}

/**
 * Returns a random item, but does not delete it.
 * @return
 */
public Item sample() {
    if (isEmpty())
        throw new java.util.NoSuchElementException();
    int index = StdRandom.uniform(size);
    return queue[index];
}

/**
 * Returns an independent iterator over items in  random order.
 */
public Iterator<Item> iterator(){     
    return new RandomizedQueueIterator();
}

/**
 * 
 * @author Danny
 *
 */
private class RandomizedQueueIterator implements Iterator<Item>{
    RandomizedQueue<Item> rq = new RandomizedQueue<>(queue);
    @Override
    public boolean hasNext() {          
        return rq.size()!=0;
    }

    @Override
    public Item next() {    
        return rq.dequeue();
    }

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


}

/**
 * Resizes the queue array by the given size.
 * @param d
 */
private void resize(int d) {
    Item[] newArray = (Item[]) new Object[d];
    for(int i = 0;i<size;i++)
        newArray[i]=queue[i];
    queue = newArray;
}

/**
 * Unit Testing
 * @param args
 */
public static void main(String[] args) {
    RandomizedQueue<Integer> rq = new RandomizedQueue<>();
    rq.enqueue(1);
    rq.enqueue(2);
    rq.enqueue(3);
    rq.enqueue(4);
    rq.enqueue(5);
    rq.enqueue(6);
    rq.enqueue(7);

    Iterator<Integer> iterator1 = rq.iterator();
    while(iterator1.hasNext())
        System.out.println(iterator1.next());

    System.out.println();

    Iterator<Integer> iterator2 = rq.iterator();
    while(iterator2.hasNext())
        System.out.println(iterator2.next());

}
}


package a02;

import java.util.Iterator;

 public class Subset {

public static void main(String[] args) {
    //char [] c = {'b', 'a', 'C'};
    String[] c= {"hello", "hi", "howdy", "english"};
        RandomizedQueue<String> queue = new RandomizedQueue<String>();
        for (int i=0;i<c.length; i++)
            queue.enqueue(c[i]);
        int k=3;
        Iterator<String> iterator=queue.iterator();
        for (int i=0; i<k;i++) {
            System.out.println(iterator.next());
        }
}

}

In the constructor RandomizedQueue(Item[] array) you need to add a bounds check before accessing queue .

Change:

while(queue[count]!=null)

to

while(count < queue.length && queue[count]!=null)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM