CMPSCI 187: Programming With Data Structures

David Mix Barrington

Fall, 2011

<font color=blue>Solutions</font> for Practice Exam for First Midterm 

This exam is intended to be the same length, format, and difficulty as the actual first midterm to be taken on Thursday evening 29 September 2011.  There are 100 total points -- the scale of the actual exam will be determined after it is graded.


Question text is in black, solution text in <font color=blue>blue</font>.


Correction in purple added 28 September 2011.


Section 1: Java Concepts (20)


Briefly explain the difference between the two concepts in each pair (2  pts each):


a) int and Integer

An int is a primitive value that represents an integer in a certain range.  An Integer is a wrapper object that stores one int value -- as an object it can be used in generic data structures.

b) & and &&

Both are "and" operators that take two boolean values and return true if and only if both are true.  The difference is that if the first argument is false, & will still evaluate the second argument and && will not.

c) static field (or attribute) and instance field (or attribute)

A static field belongs to a class and has a single value for the entire class.  An instance field belongs to an object and has a separate value for every object in the class.

d) char and char [ ] 

A char is a primitive value representing a Unicode character.  A char [ ] is an array where each entry is a char.

e) abstract data type and data structure

An abstract data type is a specification of the fields and methods for a class.  A data structure is an actual implementation of the class, with code for all of the methods and actual java primitives or objects for all the field values.

f) return value and side effect

Any method that is not void has a return type, and the compiler will force it to return a value of that type when it returns.  A side effect is any change in any value or object outside a method that is caused by a method, other than the return value.

g) throw and throws

An instruction within a method can bring an exception into being by saying "throw new" followed by the type and name of the exception.  The word "throws" is used in the header of a method to declare that it might pass an exception on to a method that calls it.

h) Stack (in java.util) and StackADT (in L&C)

The generic Stack class is an implementation of the stack data type that is part of standard Java.  The generic interface StackADT in L&C defines the basic stack methods, and any class that implements it, such at their ArrayStack class, must have those methods.

i) object and class

A Java object is a set of data fields and a set of associated methods.  A class is a piece of Java code that defines a set of objects, by specifying their data fields and giving code for their methods.

j) .equals (for Strings) and == (for Strings)

The .equals method for Strings returns true if the calling String and the argument have the same characters in the same order.  The == operator on two Strings returns true if they are the same String, meaning that both values are references to the same object (as, for example, if one was created and the other was assigned to the first).




Section 2: Software Engineering (10)


Briefly discuss how you would make the following modifications to the code

for the specified program, with specific reference to the code (5 pts each):


a) In Project 1, to display Maze objects with row 0 at the bottom rather than the top

In the toString method of Maze, there is a loop that prints a line for each row of the Maze. If this row goes from 0 to height-1, as usual, row 0 will be printed first, at the top.  If we revise this loop to visit the rows in the opposite order, we will get row 0 at the bottom.

b) In Project 2, to search only for paths of five or fewer steps

In the path method, our stack represents a trial path, and we push a cell onto the stack when we discover that it can be added to the current path.  If before we do this, we check that the size of the stack is at most 5, and only push a new cell onto the stack when this is true, we will never get a path of longer than five steps.  (If there were a path of five steps, we would have six cells on the stack.)



Sections 3 through 6 use the following class:


    public class Dog

       private String name;

       private int age;


       public Dog (String newName, int newAge) {

             name = newName;

             age = newAge;}


       public String getName {return name;}

       public void setName (String newName) {name = newName;}

       public int getAge {return age;}

       public void setAge (int newAge) {age = newAge;}


For all code blocks in Sections 4 and 5 that do not declare new methods, 

assume that the following code is run before the block, in a Dog static method:


   Stack s = new Stack( );

   Dog [ ] pack = new Dog[3];

   Dog ace= new Dog("Ace", 6);

   Dog biscuit = new Dog ("Biscuit", 1);

   Dog cardie = new Dog ("Cardie", 3);


Assume that each new block starts after this code, without any of the other 

blocks first.



Section 3: Trace Code (15)


Determine the output value of the following methods (5 each)


(a) pack[0] = ace;

      pack[1] = cardie;

      pack[2] = ace;

      pack[2].setAge(5);

      System.out.println(pack[0].getAge( ));

We print out the age of the dog in pack[2], who is Ace. Ace's age started at 6 but was modified by the setAge command (which applied to him because he was also pack[0] at the time) and thus we output "5".


(b) s.push(cardie);

       biscuit = s.peek( );

       s.push(ace);

       cardie = s.pop( );

       System.out.println(s.pop( ).getName( ));


We push a Dog onto the stack, reset the value of "biscuit", push a second Dog onto the stack, reset the value of "cardie" to this top Dog as we pop it off, then print the name of the bottom Dog. This Dog was put into the stack as the value at that time of "cardie", the Dog named "Cardie". The subsequent changes to the value of other Dog variables do not change the value of this stack element, so its name is still "Cardie".



( c)  s.push(cardie);

       s.push(biscuit);

       s.push(ace);

       while (s.peek( ).getAge( ) != 3)

            s.pop( );

       System.out.println (s.pop( ).getName( ));


Of the three Dog objects originally pushed onto the stack, only "cardie", the bottom element,  has an age of 3.  So the other objects are popped off until this element is at the top, and when we pop it off and read its name we get "Cardie".



Section 4: Find Errors (15)


Each of the following code fragments has a specific error that either prevents it

from compiling, will cause an exception if it is run, or produces a clearly 

unintended output.  Find the error and explain what will happen (5  each)


(a) // a new method for the Dog class

      public int dogyears ( ) {

            int age;

            return age * 7;}


This method will always return 0, which is clearly unintended.  The local variable "age" overrides the field "age" of the calling Dog object, so that return seven times the former rather than the latter.  An int variable that is not initialized is set to 0.

CORRECTION: As pointed out by a student and confirmed by a compiler, this last statement is not true. While int fields are given a default value of 0, int variables are not, so that this code will not compile.


(b) for (int i = 0; i < 3; i++)

          pack[i] = new Dog("dog #" + i, i);

      for (int j = 0; j <= pack.length; j++)

          System.out.println (pack[j].getName( ));


There was a syntax error in line 4, with a square bracket going the wrong way, so this won't compile. If that is fixed, as it is above, we get a run-time error during the second loop. Since pack.length is equal to 3, the second loop runs with j equal to 3, getting an ArrayIndexOutOfBoundsException when it attempts to access the nonexistent element pack[3].


( c) pack[0] = "Ace";

       pack[1] = "Cardie";

       pack[2] = "Biscuit";


Each of these lines attempts to assign a String to a element of a Dog array, which will not compile because a String is not a Dog and thus the types are not compatible.



Section 5:  Timing Analysis (10)


Find the big-O running time of the following methods, as a function of n, the length of the input array (5 each)


(a) public void replace (Dog [ ] kennel) {

           int n = kennel.length;

           for (int i = 0; i < n; i++) {

               kennel[i] = new Dog("Cardie", 3);

               for (int j = 0; (j < 7) && (j < i); j++) 

                    kennel[i].setAge(4);}}


The inside of the outer loop sets one element of the array and then sets the age of at most seven elements, because the inner loop will execute at most seven times before j = 7 and we drop out of the loop. So we go n times through a loop that takes O(1) time, which is O(n) time overall.


(b) One solution to Discussion #2 was as follows, in pseudocode:

         // move all n containers from the ship to the left stack

         // while the left stack is not empty

         //    shift all containers from the left stack to the right, finding the lowest label

         //    shift all containers from the right stack to the left, but sending out the 

         //          first container that has that label instead of shifting it


The first line takes O(n) time because we move n containers and it takes O(1) to move a container. We will go through the while loop n times because each time through removes one element from the left stack and there are originally n elements there. In the inside of the while loop, we first shift all the current elements, which is at most n of them, doing O(1) work as each goes by to ensure that we remember the lowest label so far. The second statement of the while loop also shifts all the current elements and does O(1) work per element, for O(n) time. The inside of the while loop thus takes O(n) + O(n) = O(n) time, and thus the entire while loop takes O(n) * O(n) = O(n^2) time.


         

Section 6: Short Coding Problem (10)


Write the specified classes or methods (10 each)


a) Write a method that will take a Stack object s as its parameter and alter it as follows.  If s is empty or has just one element, make it empty.  If it has two or more, leave it with two, and these should be the original bottom two, in reverse order.  For example, if the elements were Ace, Biscuit, and Cardie (starting from the top), the stack should have Cardie and Biscuit (starting from the top) after the method is run.


    public static void alter (Stack s) {

          if (s.size( ) < 2) {

               while (!s.empty( )) s.pop( );}

          else {

               while (s.size( ) > 2) s.pop( ); // gets rid of all but bottom two elements

               Dog wasNextToBottom = s.pop( );

               Dog wasBottom = s.pop( ); // s is now empty

               s.push(wasNextToBottom);

               s.push(wasBottom);}}


Section 7: Long Coding Problem (20)


Write the specified classes with all specified methods (20 points)


b) Write classes JeopardyBoard, Category, and Question, where a JeopardyBoard object contains six Categories and each Category has a name (a String) and contains five Questions.  A Question has a text (a String),

a dollar value (an int), and a boolean telling whether it is available.  Write a method

for the Category class that returns the first available Question that

it contains, or returns null if it has no available Question.  Then write a method for

the JeopardyBoard class that takes the number of a Category as its parameter,

and returns the first available Question in that Category, or return null if there is none.


public class Question {

     private String text;

     private int value;

     private boolean isAvailable;

     public Question (String t, int v, boolean b) {

           text = t; value = v;  isAvailable = b};

     public boolean getIsAvailable ( ) {

          return isAvailable;}}


public class Category {

     private String name;

     private Question [ ] q;

     public Category (String n, Question q0, Question q1, Question q2, Question q3, Question q4) {

           name = n; q[0] = q0; q[1] = q1; q[2] = q2; q[3] = q3; q[4] = q4;}

     public Question getQuestion(int i) {

           return q[i];}

     public Question firstAvailable ( ) {

          int i = 0;

          while (i <= 4 && !getQuestion(i).getAvailable( ))

                i++;

          if (i <= 4) return q[i];

          else return null;}}


public class JeopoardyBoard {

    private Category[ ] c;

    public JeopardyBoard (Category c0; Category c1; Category c2; Category c3; Category c4; Category c5) {

          c[0] = c0; c[1] = c1; c[2] = c2; c[3] = c3; c[4] = c4; c[5] = c5;}

    public Category getC (int i) {

          return c[i];}

    public Question firstAvailableInC (int i) {

          return getC(i).firstAvailable;}}







Last modified 28 September 2011