CS W3139-02 Homework 1 Solutions



Non-Programming Problems

  1. Exercise 1.3

    void printOutD(double d, int p) {
        
      int i=0;
    
      // handle case where d is negative
      if (d < 0) {
        d *= -1;
        System.out.print("-");
      }
          
      // print out d to the precision specified by p
      for(i=0; i<p; i++)
        d *= 10;
    
      // typecast d to an int
      i = (int)(d);
        
      // print int form of d
      printOutInt(i, p-1);
     
      System.out.println("");
    
      return;
    }
    
    void printOutInt(int n, int p) {
           
      if (n >= 10)
        printOutInt(n/10, p-1);
    
      if (p == 0)
        System.out.print(".");
    
      printDigit( n % 10 );
    
      return;
    }
    

  2. Exercise 1.5

    static int ones(int n)
    {
       if (n < 2)
            return n;
       return n % 2 + ones(n/2);
    }
    
  3. Exercise 1.6

    public void permute( String str ) {
    
      char c[];
    
      c = str.toCharArray();
    
      permute(c, 0, c.length-1);
    
      return;
      
    }
    
    private void permute(char[] str, int low, int high) {
    
      char [] s = new char[str.length];
      char tmp;
    
      System.arraycopy(str, 0, s, 0, str.length);
    
      if (high == low)
        System.out.println(str); 
      else {
        for(int i=low; i<=high; i++) {
          tmp  = s[i];
          s[i] = s[low];
          s[low] = tmp;
          permute(s, low+1, high);
        }
      }
      
      return;
    
    }
    
  4. Exercise 1.12

    (a)

      SumOf(i=1 to N)(2i-1) = 2 * SumOf(i=1 to N)i - SumOf(i=1 to N)1
                            = N(N+1) - N = N^2
    
    (b) The easiest way to prove this is by indcution. The case N=1 is trivial. Otherwise,
      SumOf(i=1 to N+1)i^3 = (N+1)^3 + SumOf(i=1 to N)i^3
                           = (N+1)^3 + (N^2 * (N+1)^2)/4
    		       = (N+1)^2 * [(N^2)/4 + (N+1)]
    		       = (N+1)^2 * [(N^2+4N+4)/4]
    		       = ((N+1)^2 * (N+2)^2)/(2^2)
    		       = ((N+1)(N+2)) / 2)^2
    		       = (SumOf(i=1 to N+1)i)^2
    
  5. Exercise 1.13
    class Collection {
      
      private int capacity;
      private Object[] collection;
      private int numFull;
    
      Collection (int max) {
    
        collection = new Object[max];
        capacity = max;
        numFull = 0;
    
      }
    
      public boolean isEmpty() {
        
        return (numFull == 0);
     
      }
    
      public void makeEmpty(int max) {
        
        numFull = 0;
     
      }
    
      public void insert (Object x) {
      
        if (numFull < capacity) {
          collection[numFull++] = x;
        }
    
      }
    
      public void remove (Object x) {
       
        for(int i=0; i<numFull; i++)
          if (collection[i].equals(x)) {
            collection[i] = collection[--numFull];
            return;
          }
       }
       
       
      public boolean isPresent (Object x) {
        
        for(int i=0; i<numFull; i++) {
          if (collection[i].equals(x))
            return true;
        }
    
        return false;
      }
    
    }
    
  6. Exercise 2.1

    2/N, 37, Sqrt(N), N, NloglogN, NlogN, Nlog(N^2), Nlog^2N, N^(1.5), N^2, N^2logN, N^3, 2^(N/2), 2^N. NlogN and Nlog(N^2) grow at the same rate.

  7. Exercise 2.2

    (a) True.
    (b) False. A counterexample is T1(N) = 2N, T2(N) = N, and f(N) = N.
    (c) False. A counterexample is T1(N) = N^2, T2(N) = N, and f(N) = N^2.
    (d) False. The same counterexample as in part (c) applies.

  8. Exercise 2.7 (Part a only)

    For all these programs, the following analysis will agree with a simulation:

    1. The running time is O(N).
    2. The running time is O(N^2).
    3. The running time is O(N^3).
    4. The running time is O(N^2).
    5. j can be as large as i^2, which could be as large as N^2. k can be as large as j, which is N^2. The running time is thus proportional to N * N^2 * N^2, which is O(N^5).
    6. The if statement is executed at most N^3 times, by previous arguments, but it is true only O(N^2) times (because it is true exactly i times for each i). Thus the innermost loop is only executed O(N^2) times. Each time through, it takes O(j^2) = O(N^2) time, for a total of O(N^4). This is an example where multiplying loop sizes can occasionally give an overestimate.

  9. Exercise 2.12

    According to the problem an algorithm takes .5 ms for input size 100. We would like to determine how large a problem can be solved in 1 min. We use the fact that there are 60,000 ms in 1 min.

    We would like to solve for X where: ( .5 / 60000 ) = ( f(100) / f(X) ).

    (a) 120,000 times as large a problem, or input size 12,000,000. You solve for X in the following equation: ( .5 / 60000 ) = ( 100 / X).
    (b) Solve for X in the following equation: ( .5 / 60000) = ( (100 log 100) / (X log X) ). The solution is approximately 3.19 * 10^7.
    (c) Solve for X in the following equation: ( .5 / 60000) = ( 100^2 / X^2). The solution is approximately 34,641.
    (d) Solve for X in the following equation: ( .5 / 60000) = ( 100^3 / X^3). The solution is approximately 4,932.

    You do not need to be concerned with constant factors because they cancel with the ratios above.

  10. Exercise 2.22

    Compute X^2, X^4, X^8, X^10, X^20, X^40, X^60, and X^62.

  11. Exercise 3.5

    (a) Using public methods, a cut and paste can be done in time proportional to the amount of cut nodes.

    The following solution was written by Changbin Wang:

    public static void cutAndPaste (LinkedListItr beg, LinkedListItr end,
                                    LinkedListItr insp)
    {
      // Assume beg is the position before the cut beginning point.
      // Advance the interator.
      LinkedListItr itrtmp = beg.advance();
    
      for( ; irttmp.current != end.current; itrtmp.advance())
      {
        // If the tmp iterator doesn't reach the end iterator, insert the
        // the corresponding element in the other list
        insp.current.next = new ListNode(itrtmp.current.element, 
                                         insp.current.next);
        // Advance the temporary iterator
        insp.advance();
      }
      // Bypass the cut part in the first list
      beg.current.next = end.current.next;
    }  
    
    (b) Adding a method directly to the list class allows a cut and paste to be done in constant time. Note that there can be difficulty reforming the original list if it is not doubly-linked; it might be better to require an iterator prior to the cut point. Without the doubly linked list and the previous iterator, you can use the findPrevious method, but this will make you algorithm O(N).

    Assuming you had iterator prior to the cut point:
    //prevb is an iterator prior to the cut point, p is the paste point
    public static void cutAndPaste (LinkedListItr prevb, LinkedListItr beg, 
                                    LinkedListItr end, LinkedListItr p)
    {
      prevb.next = end.current.next;
      end.current.next = p.current.next;
      p.current.next = beg.current.next;
    }
    
    The following solution, provided by Daniel R. McCarthy, uses the findPrevious method:
    public static void cutAndPaste  (LinkedListItr startcut, 
                                     LinkedListItr endcut, 
    				 LinkedListItr startpaste)
    {
      ListNode previous = findPrevious (startcut.retrieve);
      previous.next=endcut.current.next;
      endcut.current.next = startpaste.current.next;
      startpaste.current.next=startcut.current.next;
    
    }
    

  12. Exercise 3.9

    The following solution was written by Daniel R. McCarthy

    public static LinkedList intersect (LinkedList list1, LinkedList list2)
    {
      LinkedList    result = new LinkedList();
      LinkedListItr trace1 = new LinkedListItr(list1.header);
      LinkedListItr trace2 = new LinkedListItr(list2.header);
      LinkedListItr trace3 = new LinkedListItr(result.header);
    
      trace1.advance();
      trace2.advance();
      
      while (!isPastEnd(trace1) && !isPastEnd(trace2))
      {
        if (trace1.retrieve().compareTo(trace2.retrieve()) < 0)
            trace1.advance();
        else if (trace1.retieve().compareTo(trace2.retrieve()) > 0)
            trace2.advance();
        else 
        {
            trace3.next = new Listnode(trace1.retrieve());
    	trace3.advance();
        }
      }
      
      return (result);
    }        
    

  13. public static int Fib(int N) {
    
      return fib_iter(1,1,N);
    
    }
    
    public static int fib_iter(int a, int b, int count) {
    
      if (count == 0) 
        return b;
      else
        return fib_iter(a + b, a, count - 1);
    }
    

Programming Problems

    Aro Osako had an excellent README file. You should use this as an example of what we are looking for in the README file.
    Course: W3139-002, Data Structures and Algorithm Analysis in JAVA
    Professor Nieh
    
    Homework 1, due 2/16/99
    
    Name: Aro Osako
    Email: *****@columbia.edu
    SSN#: ***-**-****
    
    ----
    Files submitted:
    	Problem 1: DecToBin.java
    		   DecToBin_Log.txt
    	Problem 2: LLADT.java
    		   LLADT_Log.txt
    		   /DataStructures/Comparable.java
                       /DataStructures/Hashable.java
                       /DataStructures/LinkedList.java
                       /DataStructures/LinkedListItr.java
                       /DataStructures/ListNode.java
                       /DataStructures/MyInteger.java
    
    ###################################
    
    Problem 1 - DecToBin
    ----
    This program will prompt the user for an integer input, then print out the
    binary equivalent of the integer.
    When dealing with negative numbers, the program will utilize 2' complement
    methodology.
    It will only take integers for inputs.
    
    Known Issues: entering a non-integer results in termination of program. 
    
    To Compile: Type "javac DecToBin.java" at CUNIX prompt.
    
    To Run: After compiling, type "java DecToBin" at CUNIX prompt.
    
    Log File: Contains several test runs of DecToBin using integers -32 to 32.
    
    ###################################
    
    Problem 2 - LLADT (Linked List Abstract Data Type)
    ----
    This program allows the user to manipulate a linked list in the following ways:
    1. Insert: prompts for integer, then adds it to the head of the list.
    2. Delete: prompts for integer, then removes its first occurence from the list.
    3. Print: prints the elements contained in the list.
    4. ReversePrint: prints the elements contained in the list in reverse order.
    5. Swap: prompts for position, then switches element at that position with the
    	 succeeding element.
    6. Flip: reverses the order of elements in the list.
    7. Quit: exits the program.
    
    Additionally, I have provided a "Help" method that displays a more detailed 
    description of each command than provided in the generic menu.
    
    It will take a single character string for input as the command (as indicated
    by the options menu), then if necessary, will take an additional integer input
    before executing the command.
    
    Known Issues: entering a zero or non-integer when prompted for integer input 
    	      results in termination of the program.
    
    To Compile: In the directory containing LLADT.java, there must exist a sub-
    	    directory "DataStructures" containing the following files:
    	    - Comparable.java
    	    - Hashable.java
    	    - LinkedList.java
    	    - LinkedListItr.java
    	    - ListNode.java
    	    - MyInteger.java
    
    	    All that being properly configured, type "javac LLADT.java" at 
    	    the CUNIX prompt.
    
    To Run: After compiling, type "java LLADT" at the CUNIX prompt. Input command
    	as indicated by the options menu.
    
    Log File: contains a sample run of the program.
    


  1. It is possible to use a very clean recursive alogrithm for this problem. You can do this by utilizing the fact that the number of bits in an integer is fixed, namely 32-bits in Java. So your recursive algorithm can manipulate an array of size 32. Initialize your array to all 0's for positive numbers, and all 1's for negative numbers (because it will be in 2's complement). You will then pass this array to your recursive method. The method will have a signature like this:
      public static void ones(int i, int carry, int a[], int count)
    
    Where i is the number to convert to binary, carry will be the carry bit for converting to 2's complement, a is your array to store the bits, and count will keep track of your current index into the array during your recursive calls. count will be begin at zero, and be incremented before every recursive call.

    It is helpful to realize the algorithm uses two different lines of recursion, one for positive numbers and one for negative numbers. Each line having its own base case and recursive calls. The base case for positive numbers will be when i is equal to 1. The recursive progress toward the base case will be obtained by dividing i by 2, where the modulus of this division will be assigned to the countth bit of the array. For positive numbers, the recursive call will always have a carry bit of 0.

    The recursion for negative numbers is similar, but slightly more involved, because we must convert the number into 2's complement (which is why we initialize the a array to all 1's for negative numbers). Our base case now will be when i is equal to -1. When we reach the base case we will assign to a[count] the carry bit, which should be 0 for the most significant bit. We still make progress toward the base case by dividing i by 2. However, after the division we will flip the bit in order to obtain the 1's complement (recall the procedure for converting to 2's complement). We will add to this the carry bit from the previous recursive call (or from the original call). If this result is not greater than 1, we will not have a carry bit on our next recursive call. So we assign a[count] the result of the addition and recurse on i/2 and a 0 carry bit. Otherwise (result > 1), we will indeed have another carry bit, so we assign a[count]=0 and recurse on i/2 and a 1 carry bit.

    Note that for a negative number, our original method call will have a carry bit of 1. This will have the effect of taking the 1's complement of the number and adding 1 to it, which is precisely how we convert to 2's complement. When the recursion ends we print out the array starting from the the 31st (32-1) index. Here is the code for this algorithm:

    import java.io.*;
    
    public class binary{
      final static int SIZE = 32;
    
      public static void ones(int i,int carry,int a[],int count){
        int rem;
        
        if (i > 0 && i < 2)           /* base case for positive i */
          a[count] = i;               /* i=1 since MSB should be 1 */
        else if (i > 0) {             /* recursive case for positive i */
          a[count++] = i % 2;
          ones(i / 2, 0, a, count);
        }
        else if (i < 0 && i > -2) {   /* base case for negative i */
          a[count] = carry;           /* MSB should be 0 after 1's comp */
        }
        else if (i < 0) {             /* recursive case for negative i */
          rem = ((-i % 2)==1)?0:1;    /* take remainder and do 1's comp */
          rem += carry;               /* add carry from prev bit for 2's comp */
          if (rem > 1) {              /* if 1's comp plus carry is 2 */
    	a[count++] = 0;
    	ones(i / 2, 1, a, count);
          }
          else {                      /* if no need to carry again */
    	a[count++] = rem;
    	ones(i / 2, 0, a, count);
          }
        }
      }
      
      public static void main(String args[]){
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String buff = null;
        boolean exit = false;
        int i=0, j, count;
        int a[] = new int[SIZE];
    
        while(!exit) {
          try{
    	System.out.print("Please enter an integer: ");
    	i = Integer.parseInt(in.readLine());
    	exit = true;
          }
          catch(Exception e) {           //Error Handling
    	System.out.println("Error.  Invalid entry.\n");
          }
        }
        
        count = 0;
        
        if (i < 0)                    /* initialize 1's in array if neg */
          for (j = 0; j < SIZE; j++)
    	a[j] = 1;
        else
          for (j = 0; j < SIZE; j++)    /* initialize 0's in array if pos */
    	a[j] = 0;
        
        if (i < 0)
          ones(i, 1, a, count);
        else
          ones(i, 0, a, count);
        
        System.out.print("The binary representation of "+i+"is:\n\t");
        
        for (j = SIZE-1; j >= 0; j--)
          System.out.print(a[j]);
        
        System.out.println("");
      }
    }
    

    Here is another solution, written by Athanasios Sarafis:
    import java.io.*;   //     A.SARAFIS
    import java.util.*; //     HW1 , CS3139
                        //It prints out the binary representation
                        //of an integer in 32-bit 2's complement format.
    public  class  Binary {
    
      private  char [ ]  array ;
      private  final  static String  exit = "exit";
      private  static String s ;   
    
      //Constructor
      public Binary ( ) {
    
      s = "" ;
      array = new  char [ 32 ];       //to represent a 32-bit
      for (int i = 0 ; i < 32 ; i++ )
         array [ i ] = '0' ;
    
      }
          
      public static void main (String[ ] args) throws IOException {
    
        String  input = "";
        int     number = 0 ;
    
        //Create an object from Binary
        Binary bi = new  Binary( ); 
        BufferedReader  response = new  BufferedReader
                (new InputStreamReader ( System.in ) ) ;
    
        StringTokenizer  st ;        // to tokenize the input
    
        while ( !input.equals(exit)) {      
          System.out.println (" To Exit Type :  exit " );
          System.out.print ("Otherwise , enter an integer  :" );
          System.out.flush ( );
          try {
            input = response.readLine( ); //read the input into a string
            st = new StringTokenizer ( input );
            input = st.nextToken( ); //give back input only its 1st token
                           
            if ( input.equals ( exit ) )
              System.exit(-1) ;
            else {
              number = Integer.parseInt (input ); //convert to int
    
              s = bi.transformation (number );  //convert to binary
              //Put the characters of s into the array
              bi.intoArray ( s );
                       
              if ( number >= 0 )
                bi.printArray (number ) ;     //immediately
              else {
                bi.neg_transformation ( ) ; // that is elaborate more
                bi.printArray (number ) ;     
              }//else
            }//else
          }//try
          catch ( Exception e ) {
            System.out.print ("That Was Not An Integer !" );
          }
        }//while
      
      }//main
    
      //Transform the int  in its binary representation
      //assuming it is always positive.This is as much
      //recursive as I can get.
      private  String  transformation ( int n ) { 
    
        int temp = 0 ;
    
        if ( n >= 0 )
          temp = n ;
        else
          temp = -n ;     // so temp is always positive
    
                              
        if (temp >= 2 )
          //reduce the problem and count the recursions
          transformation ( temp/2 ) ;     
        //put the  bin-digit into a string
        s = new String ( s+temp % 2);  
    
        return  s ;
      }//method transformation
                        
      //In case the number input is negative
      private  void  neg_transformation ( ) {
    
      //1's complement
      for ( int i = 0 ; i < array.length ; i++ ) {
        if (array [ i ] == '0')
          array [ i ] = '1' ;
        else
          array [ i ] = '0' ;
       }//for
    
       //add 1
       if ( array [ 31 ] == '0' )
         array [ 31 ] = '1' ;
       else {
         int x = 31 ;   
         while ( array [ x ] != '0' && x > 0 ) {
           array [ x ] = '0' ;
           x--;
         }
         //finish the addition
         array [ x ] = '1' ;
       }//else
    
       }//method neg_transformation
    
       private void  intoArray (String t) {
    
         for (int i = t.length( ) ; i > 0 ; i-- )
           array [31-i +1] =t.charAt( t.length ( )-i );
    
       }//method  intoArray
    
       //Print the 32-bit
       private void printArray( int y ) {
    
         System.out.println(" The binary representation of  "+y);
         System.out.print (" is  :");
         for ( int i = 0 ; i < array.length ; i++ ) 
           System.out.print (array [ i ]);
    
           System.out.println( );
    
           //clean the house
           for ( int i = 0 ; i < array.length ; i++ ) 
             array [ i ] = '0';
           s = "";
       }
    
    }//class Binary
    


  2. The following solution was written by Vipinjeet Singh Sandhu

    File ListNode.java:

    //This is the class for Nodes in a Linked List
    class ListNode
    {
      // Constructors
      ListNode( Integer theElement )
      {
        this( theElement, null );
      }
    
      ListNode( Integer theElement, ListNode n )
      {
        element = theElement;
        next    = n;
      }
    
      Integer   element; //object which this node contains
      ListNode next; //Reference to next node.
    }
    
    File LinkedListItr.java
    import ListNode.*;
    /*
     * This is the LinkedList Iterator Class
     */
    public class LinkedListItr
    {
      //Constructor
      LinkedListItr( ListNode theNode )
      {
        current = theNode;
      }
    
      //Obvious, but also just tells if the Iterator is a null
      //reference
    
      public boolean isPastEnd( )
      {
        return current == null;
      }
    
      //Function returns element of node which Iterator points to
      public Integer retrieve( )
      {
        return isPastEnd( ) ? null : current.element;
      }
    
      //Points Iterator to next node in list
      public void advance( )
      {
        if( !isPastEnd( ) )
          current = current.next;
        }
    
        ListNode current;    // Current position
      }
    
    File: Stack.java
    import java.io.*;
    import java.util.*;
    import ListNode.*;
    
    // This is the Stack class. It uses a linked-list implementation
    public class Stack
    {
      // Constructor
      public Stack( )
      {
        topOfStack = null;
      }
    
      // Simple Boolean function
      public boolean isEmpty( )
      {
        return topOfStack == null;
      }
    
      // "Empties" the Stack.
      // Nodes will be dealt with by garbage-collector
      public void makeEmpty(
      {
        topOfStack = null;
      }
    
      // returns the most recently added integer on the stack, without
      // actually changing the stack itself.
      public Integer top( )
      {
        if( isEmpty( ) )
          return null;
        return topOfStack.element;
      }
    
      // Removes the most recently added integer, does not return it,
      // however. See topAndPop() function.
      public void pop( ) //throws Underflow
      {
        if( isEmpty( ) ){
        //throw new Underflow( );
        }
        else{ topOfStack = topOfStack.next;}
      }
    
      // Returns the most recently added integer, and removes it from
      // the list.
      public Integer topAndPop( )
      {
        if( isEmpty( ) )
          return null;
    
        Integer topItem = topOfStack.element;
        topOfStack = topOfStack.next;
        return topItem;
      }
    
      // Puts an integer on the stack.
      public void push( Integer x )
      {
        topOfStack = new ListNode( x, topOfStack );
      }
    
      private ListNode topOfStack;
    
    }
    
    File: LinkedList.java:
    import ListNode.*;
    import LinkedListItr.*;
    import Stack.*;
    import java.io.*;
    import java.util.*;
    
    // This is the LinkedList Class
    
    public class LinkedList
    {
      //Main Fxn.
      public static void main (String args[]){
        MenuFunction();
        return;
      }
    
      // Data Attributes
      private ListNode header;
      private ListNode tail;
    
      // Constructors
      public LinkedList( )
      {
        header = new ListNode( null ); 
        tail = header;
      }
    
      // Obvious boolean fxn.
      public boolean isEmpty( )
      {
        return null == header.next;
      }
    
      // "Empties" the list of all its nodes.
      // If the nodes are not referred to by other objects,
      // they will be garbage-collected.
      public void makeEmpty( )
      {
        header.next = null;
      }
    
      // Gives back an Iterator to the header node of the list
      public LinkedListItr zeroth()
      {
        return new LinkedListItr(header);
      }
    
      // Gives back an Iterator to the first node in the list.
      // Obviously, the reference is null if there are no nodes.
      public LinkedListItr first( )
      {
        return new LinkedListItr( header.next );
      }
    
      //Gives back an Iterator to the last node in the list.
      //Obviously, the reference is null if there are no nodes.
      public LinkedListItr last()
      {
        return new LinkedListItr(tail);
      }
    
      // Inserts x in a new node after the one which p points to.
      // If the Iterator is null, the insertion fails, no errors
      // occur, however.
    
      public void insert( Integer x, LinkedListItr p )
      {
        if( null != p && null != p.current )
          p.current.next = new ListNode( x, p.current.next );
        if(p.current  == tail)
          tail = tail.next;
      }
    
      // Returns an Iterator to the first instance of x in the
      // list. Iterator is null if x is not found.
      public LinkedListItr find( Integer x )
      {
        ListNode itr = header.next;
    
        while( null != itr && !itr.element.equals( x ) )
          itr = itr.next;
        return new LinkedListItr( itr );
      }
    
      // Returns an Iterator to the node before the first instance of
      // integer x. If x is not found, points to last element in the list.
      public LinkedListItr findPrevious( Integer x )
      {
        ListNode itr = header;
    
        while( null != itr.next  && !itr.next.element.equals( x ) )
          itr = itr.next;
    
        return new LinkedListItr( itr );
       }
    
       // Removes the first instance of Integer x in the list
       // If integer x not found, list is unchanged.
       public void remove( Integer x )
       {
         LinkedListItr p = findPrevious( x );
         if (null == p.current.next)
           System.out.println("Integer: "+x+" not in list.");
         else{
           if(p.current.next==tail)
             tail = p.current;
    	 p.current.next = p.current.next.next;}  // Deleted node
    						      // is garbage-collected
    	    
       }
    
       // Just prints the list
       public static void printList( LinkedList theList )
       {
         if( theList.isEmpty( ) )
           System.out.print( "Empty list" );
         else
         {
           System.out.print("Your List: ");
           LinkedListItr itr = theList.first( );
           for( ; !itr.isPastEnd( ); itr.advance( ) )
             System.out.print( itr.retrieve( ) + ",  " );
         }
    
           System.out.println( );
       }
    
    
    //These are all private functions that make a nice interface, and
    //wrapper functions which call the real routines.
    
    // MenuFunction() = Workhorse of the main() function
    // calls a menu method, and routes the program based on that method's
    // output.
    private static void MenuFunction()
    {
      LinkedList L = new LinkedList();
      String[] menuOptions= {"Insert an integer", "Delete an Integer",
    			 "Print the List", "Print the List in Reverse Order",
    			 "Swap Two Elements", "Reverse the Entire List",
    			 "Exit the Program"};
      boolean again = true;
      while (again){
        int menuchoice = GetMenuChoice(menuOptions);
        switch (menuchoice){
        case 1: L.Insert(); break;
        case 2: L.Delete(); break;
        case 3: printList(L); break;
        case 4: L.PrintReverse(); break;
        case 5: L.Swap(); break;
        case 6: L.Reverse(); break;
        case 7: again = false; break;
        default: System.out.println("you chose: "+menuchoice); break;
        };
      }
      return;
    }
    
    //Takes in array of strings, shows menu, returns number of the menu
    //choice made
    private static int GetMenuChoice(String [] menuOptions)
    {
      System.out.println("\n------------------------------------------");
      System.out.println("Please choose from menu below:");
      for (int i=0; imenuOptions.length))
        choice = GetInteger("Type the number of the option you want: ");
      return (choice);
    }
    
    //This version is just default of one below
    private static int GetInteger()
    {
      return(GetInteger("Enter an Integer: "));
    }
    
    
    //Just an exception-proof integer input function
    private static int GetInteger(String s)
    {
      BufferedReader in = new BufferedReader(new
    					 InputStreamReader(System.in));
      while(1<2){
        try{
          System.out.print(s);
          System.out.flush();
          String oneLine = in.readLine();
          StringTokenizer st = new StringTokenizer(oneLine);
          int i = Integer.parseInt(st.nextToken());
          return (i);
        }catch(Exception ioe){
          System.out.println("IO error:" + ioe);
        }
      }
      return (0);
    }
    
    //Delete and Insert are pass-through functions
    private void Insert()
    {
      int i = GetInteger("Please type in the integer you would like to insert: ");
      insert((new Integer(i)), last());
      return;
    }
    
    private void Delete()
    {
      int i = GetInteger("Enter the integer which you would like to delete: ");
      remove(new Integer(i));
      return;
    }
    
    private void PrintReverse()
    {
      Stack s = new Stack();
      LinkedListItr itr = first();
      while (!itr.isPastEnd()){
        s.push(itr.retrieve());
        itr.advance();
      }
      System.out.print("Your reversed list is: ");
      while (!s.isEmpty()){
        Integer i = s.topAndPop();
        System.out.print(i+", ");
      }
    }
    
    private void Swap()
    {
      int i = GetInteger
      ("Enter the position of the node to be swapped with its successor:\n");
      if(i>0){
        ListNode itr = header;
        while((--i>0)&&(null != itr.next)){
          itr = itr.next;
        }
        if ((null != itr.next)&&(null != itr.next.next)){
          ListNode tempItr = itr.next.next;
          itr.next.next = tempItr.next;
          tempItr.next = itr.next;
          itr.next = tempItr;
        } else {
          System.out.println
        ("That node is nonexistent or has no successor.\nSwap failed");
        }
      } else{
        System.out.println("That node is nonexistent or has no successor.\nSwap failed");
      }
    }
    
    private void Reverse()
    {
      Stack s = new Stack();
      LinkedListItr itr = first();
      Integer tempInt;
      while (!itr.isPastEnd()){
        tempInt = itr.retrieve();
        s.push(tempInt);
        remove(tempInt);
        itr = first();
      }
      while (!s.isEmpty()){
        insert(s.topAndPop(), last());
      }
    }
    }
    

    [ CS3139 Home]