Exam One Sample Solutions
Q1. [16 points] This question tests your basic knowledge of the Java for statement. Convert the following sequence of statements into a for statement where the invocation of System.out.println only appears once.
+4 | Having syntax of for loop:
for (INIT ; TEST; ADVANCE) { |
+3 | Valid INIT |
+3 | Valid TEST |
+3 | Valid ADVANCE |
+3 | Valid use of System.out.println (...) |
There are so many possible solutions. Here are three that I found interesting (the first is the way I would have done it)
for (int i = 8; i >= 0; i = i -2) { System.out.println ( i*i ); } |
int []ar = {64,36,16,4,0}; for (int i = 0; i < ar.length; i++) { System.out.println (ar[i]); } |
for (int i = 64; i >= 0; i--) { if (i==64 || i == 36 || i == 16 || i == 4 || i ==0) { System.out.println (i); } |
Q2. [20 points] Please circle either TRUE or FALSE for each statement.
Note because of the large class size and the inherent visual problems with T/F exams, there were two exams printed. All answers are here:
To instantiate an array of 8 boolean values use the Java
statement: boolean [] ba = new boolean(8); |
FALSE -- note that the 8 must be in [8]. |
Assuming that d is a variable of type double,
while i is a variable of type int, the following statement is
valid: i = d; |
FALSE -- double has too much information and must be manually cast to an int. |
Alternate questions were as follows:
To instantiate an array of 8 boolean values use the Java
statement: boolean [] ba = new boolean[8]; |
TRUE |
Assuming that d is a variable of type double,
while i is a variable of type int, the following statement is
valid: d = i; |
TRUE -- can always cast an int to a double |
The following questions were the same on both tests.
To overload a method, a programmer simply declares that a method can throw an Exception | FALSE -- overloading is to have another method with a different parameter list |
Given a rectangle with int sides x and y as shown, the
perimeter is calculated by the Java statement: int p = 2*x+y; |
FALSE -- the proper expression is 2*(x+y) |
Q3. [20 points] There are at least five logical errors in the following
code that compiles successfully. The code is supposed to read in two numbers and
then print them out in increasing order. Instead, after following the
instructions given by the prompt, the program throws an Exception and terminates
with no output. Circle where the error(s) occur in the code.
Each logical error was worth four points. There are six in the program
import
java.util.Scanner; public class Test { static int []list; static int tmp; static void order (int a, int b) { if (list[a] > list[b]) // NOTE LACK OF { ... } AFTER IF STATEMENT tmp = list[a]; list[a] = list[b]; list[b] = tmp; } public static void main (String []args) { Scanner sc = new Scanner (System.in); System.out.println ("Enter two numbers separated by commas"); int []list = new int [2]; int low = 1; int high = 2; list[low] = sc.nextInt(); list[high] = sc.nextInt(); order (low, high); System.out.println (list[0] + list[1] + " are increasing."); } } |
Q4. [20 points] Given the following code, fill in the diagram with appropriate references. Show all objects, variables (static, instance, and local) and parameters including values or references as appropriate. Note that the program is stopped at the comment.
public class Value {
public int x;
Value next;
public Value (int x) {
this.x = x;
next = null;
}
}
public
class Sample {
static Value inspect (Value p) {
if (p.x <
5) {
return p;
}
return null;
}
static void update (Value x, Value y) {
x.next = inspect(y);
// STOP AND DRAW HERE.
}
public static void main (String args[]) {
Value p = new Value (5);
Value q = new Value (3);
update (p, q);
}
}
+4 | Having boxes for p and q in the local variables section of main, and having arrows coming out of them pointing (one each) to the objects |
+2 | labeling lower box main |
+2 | having an argument args in the argument to main |
+2 | having second box labeled updated |
+2 | having x and y arguments within update properly pointing to the objects, x to the object pointed to by p and y to the object pointed to by q. |
+4 | for having the object pointed to by p to have an x box with "5" inside it, and a next box pointing to the other object. |
+4 | for having the object pointed to by q to have an x box with "3" inside it and a next box pointing to null |
Q5. [2 points] fill in this Dilbert cartoon. Extra points if I fall out of my chair laughing.
Q6. Design an append method for the List class that maintains an ordered list of int values (always appending to the end) but ensures that an Exception is thrown if one tries to append an int already in the list.
(a) [6 points] Write the declaration for
append.
(b) [8 points] Write the method
implementation for append.
(c) [8 points] Describe in English the
test cases for append.
public class
Node { int x; Node next; public Node (int x) { this.x = x; next = null; } } |
public class
List { Node head; public List () { head = null; } }
|
(a) [6 points] public void append (int i ) throws Exception { ... }
+2 | public void append |
+2 | int i as an argument [also allowed Node n] |
+2 | throws Exception |
Note that append should not be a method of the Node class. Note that it is inappropriate for the append method to be a static method of the List class. For example, if you made a method 'public static void append (List l, int i) throws Exception' this would be syntactically correct, but you would be missing out on the opportunity of using an instance method.
Tangent: This yellow box is not required for answering the problem; I wanted to show a point.s | ||
For example, consider the difference in these three methods whose purpose is to count the number of Node objects in a linked list. | ||
// Defined in the
Node class public class Node { int x; Node next;
/** |
// Defined
static in List public class List { Node head;
/** Return number of Nodes in
return ct; |
// proper solution public class List { Node head;
/** Return number of Nodes in
return ct; |
(b) [8 points] Write the method implementation for append
A few students were confused as to exactly what I was asking. I used the append example in class several times (together with provided handouts). Append simply means to take a list and append something to the end of the list. There is thus an implied ordering, which is based on the order in which append was invoked. Thus if someone used append four times -- once with 2, once with 54, once with 3 and once with 10 -- then the List would have the following Nodes in the following order:
head: | 2 |
next one in the List: | 54 |
third one in List | 3 |
last one in List | 10 |
Thus there was no mandate that you were required to sort the elements as they were being ordered.
To handle append, you needed to break down the solution into its parts
public void append (int i) throws Exception { // what if current List (i.e., this) has no nodes and is empty?
// verify
that value doesn't currently exist in the List. // append
new Node whose value is i to the end of the List |
Now that we know the scope. Let's tackle each in turn:
public void append (int i) throws Exception { // what if current List (i.e., this) has no nodes and is empty? if (head == null) { head = new Node (i); return; }
// verify that value doesn't currently exist in the List. // append
new Node whose value is i to the end of the List |
We can safely return within the if statement (and MUST do so to avoid a sneaky defect).
public void append (int i) throws Exception { // what if current List (i.e., this) has no nodes and is empty? if (head == null) { head = new Node (i); return; }
// verify that value doesn't currently exist in the List. // append
new Node whose value is i to the end of the List |
Now we only need to add the append implementation.
public void append (int i) throws Exception { // what if current List (i.e., this) has no nodes and is empty? if (head == null) { head = new Node (i); return; }
// verify that value doesn't currently exist in the List. // append
new Node whose value is i to the end of the List. Note that |
It is possible to make this a bit more efficient by combining the verify and append sections of the code, but by doing so, you run the risk of introducing a defect.
(c) [8 points] Describe in English the test cases for append.
+2 | testing the append of int x into empty list (where List has no nodes) |
+2 | testing the append of int x into a list (of any size) that doesn't already have that integer. |
+2 | testing the append of int x into a list where x is the last number in the list |
+2 | testing the append of int x into a list where x is the first number in the list |
testing the append of int x into a list where x is somewhere in the middle of the list |
Why do I bother with three cases for insert where x is in the list? Basically, you must look at the code above to see why. First, there is only one way that a number can't be in a list (right?) but there is any number of ways that one could try to append a number. When thinking about the problem, I found that the last while loop was tricky (having to remember to stop when 'ptr.next == null' not just when 'ptr == null') so I thought it was worthwhile to have two test cases to verify I got the code right. When you look at your code, see if you didn't make a similar mistake in your (b) implementation that would have allowed you to append an int that was the last one in the list.