Question text is in black, solutions in blue.
Q1: 20 points Q2: 10 points Q3: 15 points Q4: 15 points Q5: 10 points Q6: 10 points Q7: 20 points Total: 100 points
import java.util.*; // we will use Stack
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;}}
In Questions 3 and 4, the following code block B is to be run before some of the given code blocks, in a static method of the class Dog:
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);
The single = is the assignment operator, which sets the variable on the left equal to the value of the expression on the right. The double == is the equality operator, which returns a boolean that is true if the things on each side are "equal" -- the same value for primitives or the same object for objects.
A static method is called from a class and may use only class data, not instance data. An instance method is called from a particular object and may use the instance data for that object.
An exception is caught if it occurs within a try block and there is a catch block for exceptions of that type. If this happens the catch block is run and the execution continues. Any other exception is uncaught and halts the execution.
Every variable has a type, which governs which values it may hold -- only values of compatible types. An object has a class from the time it is created with a constructor, and this class remains constant even if the object becomes the value of variables with different types.
Terrier
and (Terrier)
"Terrier" is the name of a class in our examples. "(Terrier)" is a cast operator -- if it is called on an object that can fit into a Terrier variable, the cast allows the interpreter to put it there, even if the compiler cannot verify that the object will fit. If the object cannot fit into a Terrier variable we get a ClassCastException.
char
and Character
The primitive type char holds a single Unicode character. The wrapper class Character defines objects that hold a single value of type char.
Creating an array, usually with a "new" statement, allocates memory for the array and defines its size. Populating the array means assigning individual values for the memory locations created.
A parameter is a value passed to a method when it is called -- the names and types of all parameters appear in the method's signature. A local variable is one defined within the method, and it stops being defined when the method ends.
A class defines the fields of an object and has code for its associated methods. An interface is a list of methods with their signatures -- a class implements the interface by providing code for all those methods.
&&
and ||
The boolean operator && is a short-circuit AND -- it evaluates its left-hand size and if that is true, evaluates the right-hand side. It returns "true" if and only if both sides evaluate to true. The boolean operator || is a short-circuit OR -- it evaluates its left-hand side, evaluates the right-hand side only if the left-hand side is false, and returns "true" if and only if at least one of the sides evaluates to true.
String
, in addition to its existing
attributes.
Add a new data field public String label
to the Cell class.
Add set and get methods for this field. Modify the constructor to allow
a user to set this field in a new object. In the Maze class, we may want
to modify the constructor to set the label fields of the cells in the maze.
Modify the moves
method so that instead of returning up to
four horizontal or vertical neighbors that are open, it returns up to eight
horizontal, vertical, or diagonal neighbors that are open. There should be
no modifications needed to the path method.
for (int i = 0; i < pack.length; i++)
pack[i] = new Dog("Ace", 6);
int sum = 0;
for (int j = 0; j < pack.length; j++)
if (pack[j] == ace) sum += pack[j].getAge( );
System.out.println (sum);
The value printed is 0. The new dogs in the array are not equal to the
dog ace
created in block B, though they have the same name
and age. Thus nothing is ever added to sum
.
s.push (ace);
s.push (biscuit);
s.push (cardie);
int sum = 0;
for (int i = 0; i < s.size( ); i++)
sum += s.peek( ).getAge( );
System.out.println (sum);
The value printed is 9. The dog cardie
, whose age is 3,
is on the top of the stack after the pushes. We peek at its age three
times, without changing the stack, and add those three 3's together.
for (int i = 0; i < 3; i++) {
s.push (ace);
s.push (cardie);}
while (s.size( ) > 3)
s.pop ( );
System.out.println (s.peek( ).getName( ));
The value printed is the string "Ace". We push six elements onto the stack,
then pop elements off until three are left. At this point ace
is the top element of the stack, as we popped off cardie
,
ace
, and cardie
in that order.
pack[0].setName("Ace");
pack[1].setName("Cardie");
pack[2].setName("Biscuit");
The array pack
has been created but not populated in block B.
The first statement attempts to call a method from pack[0]
, which
is null, and throws a NullPointerException.
public String toString (String name, int age) {
String w = name + ", age: " + age;
return w;}
This code will compile and run, but produce unintended output. (There is nothing wrong with the use of + in the second line.) The programmer probably wanted to override the toString method of Object, but did not because that method has no parameters and this method has two. Also, a toString method normally gives a string with information about the calling object, but this method returns a string based on the parameters given it, not on the instance data.
Dog [ ] [ ] superpack = new Dog [5] [3];
for (int j = 0; j < 5; j++)
for (int i = 0; i < 3; i++)
superpack [i] [j] = ace;
This code will throw an ArrayOutOfBoundsException if run, as soon as the j loop gets to 3. (The code would run without an exception if the i and j in the last line were switched.)
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 < i; j++)
kennel[j].setAge(4);}}
We go exactly n times through the outer loop. The inner loop executes i times for each value of i, which means the the total number of executions of the inner loop is proportional to 1 + 2 + 3 + ... + n which is O(n2).
// while (the ship has more containers) {
// unload the next container from the ship into temp storage
// shift containers from left to right or right to left
// as needed until the label of the new container is
// between the labels of the top containers of the
// left and right stacks
// push the new container onto the left stack
// shift all containers to the right stack
// pop and send out each container in turn from the right stack
The while loop executes n times, once per container offloaded from the ship. Inside the while loop, the shifts will take time depending on the labels of the containers but certainly (in the worst case) proportional to the number of containers that have been offloaded so far. So the while loop in all takes O(n2) just as in part (a) of this question. The two operations after the while loop take O(n) each, and O(n2) + O(n) + O(n) = O(n2).
ShowDog
extending the class Dog
from
above. Along with its Dog
atttributes, a
ShowDog
object will have two new attributes, its
breed (stored as a String
) and its entry number
(stored as an int
). Write a new four-parameter
constructor for the ShowDog
class, allowing the
user to set all four attributes. (You need not write get and
set methods for the new attributes.)
public class ShowDog extends Dog {
private String breed;
private int entryNo;
public ShowDog (String newName, int newAge, String newBreed, int newEntry) {
super (newName, newAge);
breed = newBreed;
entryNo = newEntry;}}
Square
and Chessboard
as follows. A
Chessboard object has an 8 by 8 two-dimensional array of Square
objects. Each Square object has two attributes -- its contents,
which consist of a ChessPiece
object (where we
assume that the ChessPiece
class is already
defined), and an number called grains
, stored as an
int
. Write get and set methods for each attribute
of Square. Write methods public Square getSquare(int i,
int j)
and public void setSquare(int i, int j,
Square s)
for the Chessboard class. You are not asked to
write constructors for either class.
The grains
attribute refers to the legend in
which the inventor of chess asks for the following reward -- one
grain of wheat for the first square of the board, two for the
second, four for the third, and so on for the whole board.
Write a method reward
in the Chessboard class that
will set the grains
attribute of each square of the
board as follows. The square (0, 0) gets one grain, and then
each
square in turn gets twice the number of the preceding squre, in
the order (0, 0), (1, 0), ..., (7, 0), (0, 1), (1, 1), ..., (7,
7). (Your method should assume that the board has been created
and populated with valid Square objects.)
What is the value of the grains
attribute of square
(7, 7) after your method has been run?
The number of grains on the last square would be 263, from
doubling 1 a total of 63 times, except that this number is too large to be
stored in the The order of the loops is important in order to visit the squares in the
order that I specified.
public class Square {
private ChessPiece piece;
private int grains;
public ChessPiece getPiece {return piece;}
public void setPiece (ChessPiece newPiece) {piece = newPiece;}
public int getGrains {return grains;}
public void setGrains (int newGrains) {grains = newGrains;}}
public class Chessboard {
private Square [ ] [ ] board = new Square [8] [8];
public Square getSquare (int i, int j) {return board [i] [j];}
public void setSquare (int i, int j, Square s) {board [i] [j] = s;}
public void reward ( ) {
int g = 1;
for (int y = 0; y < 8; y++)
for (int x = 0; x < 8; x++) {
board[x][y].setGrains(g);
g *= 2;}}}
int
variable that I carefully specified. If you
double any 32 times, it becomes 0, and so this value is 0. (This was
a tricky an perhaps not entirely fair point, and actually no one
completely got it, but I was happier with the five or six people who recognized
that there was a problem with the number being too big. (Even if they thought
there would be an exception, which there isn't.)
Last modified 4 October 2011