Coursera-Algorithms,Part I-Robert Sedgewick-Programming Assignment 2

Programming Assignment 2:Deques and Randomized Queues

問題描述

Deque.java

// import java.util.Scanner;  // Uncomment this line when using client testing
import java.util.Iterator;

public class Deque<Item> implements Iterable<Item> {

    private Node first;
    private Node last;
    private int size;

    private class Node
    {
        Node next;
        Node previous;
        Item item;
    }

    public Deque()                           // construct an empty deque
    {   
        first = null;
        last = null;
        size = 0;
    }

    public boolean isEmpty()                 // is the deque empty?
    {   return size == 0;   }

    public int size()                        // return the number of items on the deque
    {   return size;    }

    public void addFirst(Item item)          // add the item to the front
    {
        if (item == null)
        {   throw new java.lang.IllegalArgumentException(); }
        Node oldFirst = first;
        first = new Node();
        first.item = item;
        first.next = oldFirst;
        first.previous = null;
        if (isEmpty()) last = first;
        else oldFirst.previous = first;
        size++;
    }

    public void addLast(Item item)           // add the item to the end
    {
        if (item == null)
        {   throw new java.lang.IllegalArgumentException(); }
        Node oldLast = last;
        last = new Node();
        last.item = item;
        last.previous = oldLast;
        last.next = null;
        if (isEmpty()) first = last;
        else oldLast.next = last;
        size++;
    }

    public Item removeFirst()                // remove and return the item from the front
    {
        if (isEmpty()) throw new java.util.NoSuchElementException();
        Item item = first.item;
        first = first.next;
        if(first == null) last = null;
        else first.previous = null;
        size--;
        return item;
    }

    public Item removeLast()                 // remove and return the item from the end
    {
        if (isEmpty()) throw new java.util.NoSuchElementException();
        Item item = last.item;
        last = last.previous;
        if (last == null) first = null;
        else last.next = null;
        size--;
        return item;
    }

    public Iterator<Item> iterator()         // return an iterator over items in order from front to end
    {   return new IteratorDeque(); }

    private class IteratorDeque implements Iterator<Item>
    {
        private Node current = first;
        public boolean hasNext()
        {   return current != null; }
        public Item next()
        {   
            if (!hasNext())
            {   throw new java.util.NoSuchElementException();   }
            Item item = current.item;
            current = current.next;
            return item;    
        }
        public void remove()
        {   throw new java.lang.UnsupportedOperationException();    }
    }

    public static void main(String[] args)   // unit testing (optional)
    {
        System.out.println("client starts:");


//      Deque<String> deque = new Deque<String>();
//      Scanner scanner = new Scanner(System.in);
//      String str;
//      boolean ifFirst = false;
//      Iterator<String> iterator = deque.iterator();
//      while (true)
//      {      
//          if (ifFirst) System.out.println("Operation on First:");
//          else         System.out.println("Operation on Last:");
//          str = scanner.nextLine();
//          if (str.compareTo("quit") == 0) break;
//          if (str.compareTo("none") == 0) 
//          {   
//              ifFirst = !ifFirst;
//              continue;
//          }
//          if (str.compareTo("-") == 0) 
//          {
//              if (ifFirst) System.out.println(deque.removeFirst());
//              else System.out.println(deque.removeLast());
//          }
//          else if (str.compareTo("count") == 0) System.out.println(deque.size());
//          else if (str.compareTo("all") == 0) 
//          {
//              System.out.println();
//              for (String s : deque)
//              {   System.out.print(s+" ");    }
//              System.out.println();
//          }
//          else if (str.compareTo("null") == 0) 
//          {
//              if (ifFirst) deque.addFirst(null);
//              else deque.addLast(null);
//          }
//          else if (str.compareTo("iter") == 0) 
//          {   iterator = deque.iterator();    }
//          else if (str.compareTo("remove") == 0) 
//          {   iterator.remove();  }
//          else if (str.compareTo("next") == 0) 
//          {   System.out.println(iterator.next());    }
//          else 
//          {
//              if (ifFirst) deque.addFirst(str);
//              else deque.addLast(str);
//          }
//         
//      }
//      scanner.close(); 
    }


}

RandomizedQueue.java
思路:整體上類似棧的實現,取出前將棧頂元素與棧內部隨機某個元素交換。

主類的dequeue()方法在實現這個交換時是直接對items[]數組交換的。將這種實現套用到iterator實現時,發現無法通過並行測試和嵌套測試。原因是每個iterator實例在調用next()方法的時候修改了它們共有的items[]數組,導致混亂,出現重複而無法遍歷等問題。

因此改進爲:每個iterator實例維護一個出棧順序索引數組idx[],初始化爲0,1,2…N-1。每次出棧前對該數組進行前述交換,用idx[]上的交換替代以前那種對items[]具有破壞性的交換。這時每次調用next()方法,只需要返回索引值爲idx[--current]的元素即可,即items[idx[--current]]

進一步改進爲:iterator實例初始化時就利用StdRandom.shuffle()把它打亂,免去了每次的交換。開銷上應該是差不多的,但是代碼更清晰。

// import java.util.Scanner;  // Uncomment this line when using client testing
import java.util.Iterator;
import edu.princeton.cs.algs4.StdRandom;

public class RandomizedQueue<Item> implements Iterable<Item> {
    private Item[] items;
    private int N;    

    public RandomizedQueue()                 // construct an empty randomized queue
    {
        items = (Item[]) new Object[1];
        N = 0;
    }

    public boolean isEmpty()                 // is the randomized queue empty?
    {   return N == 0;  }

    public int size()                        // return the number of items on the randomized queue
    {   return N;   }

    public void enqueue(Item item)           // add the item
    {
        if (item == null) throw new java.lang.IllegalArgumentException();
        if (items.length == N)
        {   resize(2 * items.length);   }
        items[N++] = item;
    }

    private void resize(int newSize)
    {
        // System.out.println("Resizing from " + items.length + " to " + newSize); // Debugging info
        Item copy[] = (Item[]) new Object[newSize];
        for (int i = 0; i < N; i++)
        {   copy[i] = items[i]; }
        items = copy;
    }

    public Item dequeue()                    // remove and return a random item
    {
        if (isEmpty()) throw new java.util.NoSuchElementException(); 
        swap(N-1, StdRandom.uniform(N));
        Item item = items[--N];
        items[N] = null;
        if (N == items.length / 4 && N > 0) resize(items.length / 2); 
        return item;
    }

    private void swap(int idx1, int idx2)
    {
        Item temp = items[idx1];
        items[idx1] = items[idx2];
        items[idx2] = temp;     
    }

    public Item sample()                     // return a random item (but do not remove it)
    {
        if (isEmpty()) throw new java.util.NoSuchElementException(); 
        swap(N-1, StdRandom.uniform(N));
        return items[N-1];
    }

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

    private class QueueIterator implements Iterator<Item>
    {
        private int current;    
        private int[] idx;
        public QueueIterator()
        {   
            current = N;
            idx = new int[N];
            for (int i = 0; i < N; i++)
            {   idx[i] = i; }
            StdRandom.shuffle(idx, 0, N);   
        }
//      private void swapIndex(int i, int j)
//      {
//          int temp = idx[i];
//          idx[i] = idx[j];
//          idx[j] = temp;
//      }
        public boolean hasNext()
        {   return current != 0;    }
        public Item next()
        {   
            if (!hasNext()) throw new java.util.NoSuchElementException();
            // swapIndex(current-1, StdRandom.uniform(current));
            return items[idx[--current]];   
        }
        public void remove()
        {   throw new java.lang.UnsupportedOperationException();    }
    }

    public static void main(String[] args)   // unit testing (optional)
    {
        System.out.println("client starts:");


//      // Parallel test and nested test
//      RandomizedQueue<String> queue1 = new RandomizedQueue<String>();
//      for (int i = 1; i < 4; i++)
//      {   queue1.enqueue(i + ""); }
//      RandomizedQueue<String> queue2 = new RandomizedQueue<String>();
//      for (int i = 1; i < 4; i++)
//      {   queue2.enqueue(i + 3 + ""); }
//      RandomizedQueue<String> queue3 = new RandomizedQueue<String>();
//      for (int i = 1; i < 4; i++)
//      {   queue3.enqueue(i + 6 + ""); }
//
//      RandomizedQueue<RandomizedQueue<String>> queueOfQueues = new RandomizedQueue<RandomizedQueue<String>>();
//      queueOfQueues.enqueue(queue1);
//      queueOfQueues.enqueue(queue2);
//      queueOfQueues.enqueue(queue3);
//              
//      Iterator<String> iterator1 = queue1.iterator(); 
//      Iterator<String> iterator2 = queue1.iterator(); 
//      
//      // Parallel test
//      while (iterator1.hasNext())
//      {
//          System.out.print(iterator1.next() + " ");
//          System.out.print(iterator2.next() + " \n");
//      }
//      
//      // Nested test
//      for (RandomizedQueue<String> queue : queueOfQueues)
//      {   
//          System.out.println();
//          for (String s : queue)  
//          {   System.out.print(s + " ");  }
//      }



//      // Interactive test             
//      Scanner scanner = new Scanner(System.in);
//      RandomizedQueue<String> queue = new RandomizedQueue<String>();
//      Iterator<String> iterator = queue.iterator(); 
//      String str;
//      while (true)
//      {
//          str = scanner.nextLine();
//          if (str.compareTo("quit") == 0) break;
//          if (str.compareTo("-") == 0) 
//          {   System.out.println(queue.dequeue());    }
//          else if (str.compareTo("sample") == 0) 
//          {   System.out.println(queue.sample()); }
//          else if (str.compareTo("all") == 0)
//          {   
//              System.out.println();
//              for (String s : queue) System.out.print(s + " ");
//              System.out.println();
//          }
//          else if (str.compareTo("null") == 0)
//          {   queue.enqueue(null);    }
//          else if (str.compareTo("remove") == 0)
//          {   
//              iterator = queue.iterator();
//              iterator.remove();
//          }
//          else if (str.compareTo("iter") == 0)
//          {   
//              iterator = queue.iterator();
//          }
//          else if (str.compareTo("next") == 0)
//          {   
//              System.out.println(iterator.next());
//          }
//          else queue.enqueue(str);
//      }
//      scanner.close();

    }

}

Permutation.java

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import java.util.Iterator;
public class Permutation {
   public static void main(String[] args)
   {
       int k = Integer.parseInt(args[0]);
       RandomizedQueue<String> queue = new RandomizedQueue<String>();
       while (!StdIn.isEmpty())
       {
           queue.enqueue(StdIn.readString());
       }
       Iterator<String> iterator = queue.iterator();
       for (int i = 0; i < k; i++)
       {    StdOut.println(iterator.next());    }
   }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章