CSE214 Midterm Review
This question tests your understanding of assignment statements with reference variables. What is the output of this code? Throttle t1; Throttle t2;t1 = new Throttle(100); t2 = t1; t1.shift(40); t2.shift(2); System.out.println(t1.getFlow( ));
Both t1 and t2 refer to the same throttle, which has been shifted up 42 positions. So the output is 0.42.
Describe the three kinds of class members we have used. In this section, which kinds of members were public and which were private?
We have used private instance variables, public constructors, and public methods.
Write an expression that will give a random integer between -10 and 10.
(int) (Math.random( ) * 21) - 10
What is the output from this code? int[ ] a, b;a = new int[10]; a[5] = 0;b = a.clone( ); a[5] = 42; System.out(b[5]);
0(since b is a clone of a)
Describe the extra work that must be done at the end of the clone method. Draw pictures to show what goes wrong if this step is omitted.
At the end of the clone implementation, we need an additional statement to make a sepa- rate copy of the data array for the clone to use. If we don't make this copy, then our own data array and the clone's data array will be one and the same (see the pictures on page 135).
Consider the code from the preceding question. At the end of the computation, is (t1 == t2) true or false?
At the end of the code, (t1 == t2) is true since there is only one throttle that both vari- ables refer to.
Why don't we list the bag invariant as part of the explicit precondition and postcondition of the bag methods?
Because the programmer who uses the bag class does not need to know this information.
Suppose that p is a reference to a node in a linked list of integers and p.getData( ) has a copy of an integer called d. Write two lines of code that will move p to the next node that contains a copy of d (or set p to null if there is no such node). How can you combine your two statements into just one?
The two lines of code we have in mind: p = p.getLink( ); p = listSearch(p, d); These two lines are the same as this line: p = listSearch(p.getLink( ), d);
Is the constructor really needed for the linked list version of the stack? What would happen if we omitted the constructor?
The constructor isn't needed, because any instance variable that is a reference is auto- matically initialized to null.
Which bag methods do not have the bag invariant as part of their implicit precondition?
The constructors
A method declares a Throttle variable called control, but there is not yet a throttle. What value should be assigned to control?
The control should be assigned the value of null. By the way, if it is an instance variable of a class, then it is initialized to null.
Write the invariant of the bagADT.
See the two rules on page 126.
Suppose head is a head reference for a linked list of integers. Write a few lines of code that will add a new node with the number 42 as the second element of the list. (If the list was originally empty, then 42 should be added as the first node instead of the second.)
Using techniques from Section 4.2: if (head == null) head = new IntNode(42, null); else head.addNodeAfter(42);
Suppose that t1 and t2 are throttle variables and that t1 is null but t2 refers to a valid throttle. Which of these statements will cause an error? t1 = t2; t2 = t1; t1.shift(2);
t1.shift(2) will cause an error because you cannot activate methods when t1 is null. The other two statements are fine.
Evaluate the postfix expression 2 3 - 43 +.
42
What is the output from this code? int[ ] a, b;a = new int[10]; a[5] = 0;b = a;a[5] = 42; System.out(b[5]);
42 (since a and b refer to the same array)
Suppose control is a null reference. What happens if a program tries to activate control.shift?
A NullPointerException is thrown.
What happens if you try to activate a method of the null reference?
A NullPointerException is thrown.
When should a program throw a RuntimeException?
A RuntimeException indicates a program- ming error. When you throw a Runtime- Exception, you should provide an indication of the most likely cause of the error.
The location's distance method is a static method. What effect does this have on how the method is used? What effect does this have on how the method is implemented?
A static method is not activated by any one object. Instead, the class name is placed in front of the method to activate it. For example, the distance between two locations p1 and p2 is computed by: Location.distance(p1, p2); Within the implementation of a static method, we cannot directly refer to the instance variables.
What is the meaning of a static method?How is activation different from that of an ordinary method?
A static method is not activated by any one particular object. It is activated by writing the class name, a dot, the method name, and the argument list. For example: IntArrayBag.union(b1, b2)
We talked about accessor methods and modification methods. Which kind of method often has a void return type? Why?
Accessor methods are not usually void, because they use the return value to provide some information about the current state of the object. Modification methods are often void because they change the object but do not return information.
How would you modify the calculator program in Figure 6.5 on page 330 to allow the symbol ^ to be used for exponentiation? Describe the changes; do not write out the code.
Add a new case to the switch statements in both evaluate and evaluateStackTops. In evaluateStackTops, the new case calculates operand1 raised to the power of operand2 and pushes the result back onto the numbers stack.
Do big-O time analyses of the bag's methods.
All the methods are constant time except for remove, grab, countOccurrences, and clone (all of which are linear); the addAll method (which is O(n), where n is the size of the addend); and the union method (which is O(m+n), where m and n are the sizes of the two bags).
What kind of exception is thrown if you try to pop an empty stack? Which Java Class Library defines this exception?
An EmptyStackException, which is defined in java.util.EmptyStackException.
Describe the difference between a modification method and an accessor method.
An accessor method makes no changes to the object's instance variables.
Write a few lines of code to declare a bag of integers and place the inte- gers 42 and 8 in the bag. Then grab a random integer from the bag, print- ing it. Finally, print the size of the bag.
We could write this code: IntLinkedBag exercise = new IntLinkedBag( ); exercise.add(42); exercise.add(8); System.out.println (exercise.grab( )); System.out.println (exercise.size( ));
For the linked list version of the stack, do we maintain references to both the head and the tail?
We maintain only a head reference.
The bag in the preceding question has a capacity of 10. What happens if you try to add more than 10 elements to the bag?
When the 11th element is added, the add method will increase the capacity to 21.
For the array version of the stack, which element of the array contains the top of the stack? In the linked list version, where is the stack's top?
The array version: data[manyItems-1]. The linked list version has the top at the head of the list.
If you don't implement an equals method for a class, then Java automatically provides one. What does the automatic equals method do?
The automatic equals method returns true only when the two objects are the exact same object (as opposed to two separate objects that have the same value).
Would the add method work correctly if we used ensureCapacity(manyItems + 1) without the*2?
The capacity would always be increased by one (which is enough for the one new ele- ment), but increasing one by one will be inef- ficient.
Consider the following statements: int[ ] p = new int[100]; int[ ] s = p; Which of the following statements will change the last value of p to 75? (There may be more than one correct answer.) p[99] = 75; p[100] = 75; s[99] = 75; s[100] = 75;
Either p[99] = 75 or s[99] = 75.
Suppose we implement addAll as shown in Figure 3.8 on page 142. What goes wrong with b.addAll(b)?
For the incorrect implementation of addAll, suppose we have a bag b and we activate b.addAll(b). Then the private instance variable manyItems is the same variable as addend.manyItems. Each iteration of the loop adds 1 to manyItems; hence addend.manyItems is also increasing, and the loop never ends. One warning: Some collection classes in the Java libraries have an addAll method that fails for the statement b.addAll(b). So, before you use an addAll method, check the specification for restrictions.
In general, which is preferable: an implementation that uses the node methods or an implementation that manipulates a linked list directly?
Generally, we will choose the approach that makes the best use of the node methods. This saves us work and also reduces the chance of introducting new errors from writing new code to do an old job. The preference would change if the other approach offered better efficiency.
Write some illegal expressions that are caught by the calculator program in Figure 6.5 on page 330, resulting in an IllegalArgumentException.
Here are some illegal expressions that are caught: too many right parentheses (3+4)), a missing operand (3 4), a missing right parenthesis (3+4.
Write some illegal expressions that are not caught by the calculator pro- gram in Figure 6.5 on page 330.
Here are some illegal expressions that are not caught: too many left parentheses ((3+4), missing left parenthesis 3+4).
Give the full implementation of an accessor method that returns the sec- ond item from the top of the stack without actually changing the stack. Write separate solutions for the two different stack versions.
Here is one of the two solutions (for the linked list): public E second( ) { if (top == null) throw new EmptyStackException( ); if (top.link == null) throw new NoSuchElementException( ); return top.link.data; }
Write some code that will make t1 and t2 refer to two different throttles with 100 positions each. Both throttles are shifted up to position 42. At the end of your code, is (t1 == t2) true or false?
Here is the code (and at the end, t1 == t2 is false since there are two separate throttles): Throttle t1; Throttle t2; t1 = new Throttle(100); t2 = new Throttle(100); t1.shift(42); t2.shift(42);
Implement an equals method for the Throttle class from Section 2.1.
Here is the implementation for the throttle: public boolean equals(Object obj) { if (obj instanceof Throttle) { Throttle candidate = (Throttle) obj; return (candidate.top==top)&& (candidate.position==position); } else return false; }
The add method uses ensureCapacity(manyItems*2 + 1). What would go wrong if we forgot the +1"?
If manyItems happens to be zero, then manyItems*2 would also be zero, and the capacity would not increase.
Write a new throttle constructor with no arguments. The constructor sets the top position to 1 and sets the current position to off.
In this solution, the assignment to position is not really needed, since position will be given its default value of zero before the con- structor executes. However, including the assignment makes it clear that we intended for position to start at zero: public Throttle( ) { top = 1; position = 0; }
What is the purpose of the Java constant Double.NaN?
The constant Double.NaN is used when there is no valid number to store in a double vari- able ("not a number").
Write some code that could appear in a main program. The code should declare head and tail references for a linked list of integers and then cre- ate a list of nodes with the data being integers 1 through 100 (in that order). After each of the nodes is added, head and tail should still be valid references to the head and tail nodes of the current list.
IntNode head; IntNode tail; int i; head = new IntNode(1, null); tail = head; for (i = 2; i <= 100; i++) { tail.addNodeAfter(i); tail = tail.getLink( );
Suppose head is a head reference for a linked list with just one node. What will head be after head = head.getLink( )?
It will be the null reference.
Suppose you implement a class, but you do not write a constructor. What kind of constructor does Java usually provide automatically?
Java usually provides a no-arguments con- structor that sets each instance variable to its initialization value (if there is one) or to its default value (if there is no initialization value).
Suppose I have int b = new int[42].What are the highest and lowest legal array indexes for b?
Lowest is zero; highest is 41.
How many nodes are in an empty list? What are the values of the head and tail references for an empty list?
No nodes. The head and tail are null.
Write another throttle constructor with two arguments: the total number of positions for the throttle, and its initial position.
Notice that our solution (shown at the top of the next column) has the preconditions that 0 < size and 0 <= initial <= size. public Throttle(int size, int initial) { if (size <= 0) throw new IllegalArgumentException ("Size <= 0:" + size); if (initial < 0) throw new IllegalArgumentException ("Initial < 0:" + initial); if (initial > size) throw new IllegalArgumentException ("Initial too big:" + initial); top = size; position = initial; }
What kind of exception will be thrown by these statements? int[ ] b; b[0] = 12;
NullPointerException
Repeat the previous exercise using these two initial statements: int[ ] p = new int[100]; int[ ] s = p.clone( );
Only p[99] = 75.
Do a time analysis of the size method for the linked list version of the stack. If the method is not constant time, then can you think of a different approach that is constant time?
Our size implementation uses listSize, which is linear time. For a constant-time implementation, you could maintain another private instance variable to continually keep track of the list length.
Consider the stack class given in Figure 6.1 on page 317. The peek method lets you look at the top item in the stack without changing the stack. Describe how you can define a new method that returns the second item from the top of the stack without permanently changing the stack. (If you temporarily change the stack, then change it back before the method ends.) Your description will be in terms of peek, pop, and push. Give your solution in pseudocode, not in Java.
Pop one item, storing it in a local variable called top. Then peek at the next item, storing it in another local variable called result. Push the top back on the stack and return the result.
Write the following expression in both prefix and postfix notation: ((7 + 3) * 2)
Prefix: * + 7 3 2 Postfix: 7 3 + 2 *
Suppose a program uses a stack of characters to read in a word and then write the word out backward as described in this section. Now suppose the input word is DAHL. List all the activations of the push and pop meth- ods. List them in the order in which they will be executed, and indicate the character that is pushed or popped. What is the output?
Push a D; push an A; push an H; push an L; pop an L; pop an H; pop an A; pop a D; the output is LHAD.
Use the arraycopy method to copy 10 elements from the front of an array x to the front of an array y.
System.arrayCopy(x, 0, y, 0, 10);
Suppose x and y are arrays with 100 elements each. Use the arraycopy method to copy x[10]...x[25] to y[33]...y[48].
System.arrayCopy(x, 10, y, 33, 16);
Describe one of the boundary values for testing remove.
Test the case where you are removing the last element from the bag.
In the midpoint method, we used the expression(p1.x/2)+(p2.x/2). Can you think of a reason why this expression is better than (p1.x + p2.x)/2?
The alternative (p1.x + p2.x)/2 has a subex-pression p1.x + p2.x that could result in an overflow.
Suppose an array is passed as a parameter to a method, and the method changes the first component of the array to 42. What effect does this have on the actual argument back in the calling program?
The array referred to by the parameter in the method is the same as the array referred to by the actual argument. So the actual argument will have its first component changed to 42.
What is the time analysis, in big-O notation, of the evaluation method? Explain your reasoning.
The evaluation method is linear. If n is the length of the input expression, then the main loop cannot execute more than n times (since each iteration of the loop reads and processes at least one character). Moreover, each itera- tion performs no more than a constant number of operations, so n iterations will do no more than a constant times n operations.
For the array version of the stack, write a new member function that returns the maximum number of items that can be added to the stack without stack overflow.
The function should return data.length minus manyItems.
Suppose a program builds and manipulates a linked list. What two special nodes would the program typically keep track of?
The head node and the tail node.
Add a new throttle method that will return true when the current flow is more than half of the maximum flow. The body of your implementation should activate the getFlow method.
The method implementation is: public boolean isAboveHalf( ) { return (getFlow( ) > 0.5); }
How would you modify the calculator program in Figure 6.5 on page 330 to allow for comments in the calculator input? Comments appear at the end of the expression, starting with a double slash // and continuing to the end of the line. Describe the changes; do not write out the code.
The modification is most easily accomplished in the method evaluate. Within this method, you can add a bit of code in the section that reads an operator symbol. The new code should look ahead to see whether the very next character of the Scanner is a slash (as described in Appendix B). If so, read and dis- card the rest of the line (instead of pushing the operator onto the stack).
What would go wrong if you forgot to include the listCopy statement in the bag's clone method?
The new bag and the old bag would then share the same linked list.
Which of the node methods use new to allocate at least one new node? Check your answer by looking at the documentation in Figure 4.11 on page 208 (to see which methods can throw an OutOfMemoryError).
The new operator is used in the methods add-NodeAfter, listCopy, listCopyWithTail, and listPart.
Describe two uses for the null reference in the realm of linked lists.
The null reference is used for the link part of the final node of a linked list; it is also used for the head and tail references of a list that doesn't yet have any nodes.
What kind of expressions cause the evaluation stacks to grow large?
The numbers stack grows large if the input expression has parentheses that are nested deeply. For example, consider the input expression(1 + (2 + (3 + (4 + 5)))).By the time the 5 is read and pushed onto the stack, the 1, 2, 3, and 4 are already on the numbers stack. In this example, there are four nested subexpressions, and we need to push five numbers onto the numbers stack. So, the general stack size will be one more than the depth of the nesting.
WritesomeJavacodethatcreatesanewthrottlewithsixpositions,shifts the throttle halfway up (to the third position), and prints the current flow.
The program should include the following statements: Throttle exercise = new Throttle(6); exercise.shift(3); System.out.println (exercise.getFlow( ));
What is the result when you add two double numbers and the answer is larger than the largest possible double number?
The result is the constant Double.POSITIVE_INFINITY.
Implement a clone method for the Throttle class from Section 2.1.
The solution is the same as the Location clone on page 69, but change the Location type to Throttle.
Carry out the operations of evaluate by hand on the input expression ( ( (60 + 40)/50) * (16 - 4) ). Draw the two stacks after each push or pop.
The solution is the same as the example that starts on page 327, but the numbers are changed. The final value is 24.
Trace the algorithm from Figure 6.10 on page 351 to create a postfix expression from 3 / A + (B + 12) - C.
The trace is much the same as the computation in Figure 6.11 on page 352, except that the operations are different.
Trace the algorithm from Figure 6.8 on page 347 to evaluate the postfix expression 15 9 6 * + 12 - 15 +. Draw the stack after each push or pop.
The trace is the same as the computation at the bottom of Figure 6.8 on page 347, except that the numbers are three times as large.
Use the expression --manyItems (with the -- before manyItems) to rewrite the last two statements of remove (Figure 3.5 on page 132) as a single statement. If you are unsure of the difference between manyItems-- and --manyItems, then go ahead and peek at our answer at the back of this chapter. Use manyItems++ to make a similar alteration to the add method.
The two statements can be replaced by one: data[index] = data[--manyItems];. When --manyItems appears as an expression, the variable manyItems is decremented by one, and the resulting value is the value of the expression. (On the other hand, if manyItems-- appears as an expression, the value of the expression is the value of manyItems prior to subtracting one.) Simi- larly, the last two statements of add can be combined to data[manyItems++] = element;
Look at http://www.cs.colorado.edu/~main/edu/colorado/nodes. How many different kinds of nodes are there? If you implemented one of these nodes, what extra work would be required to implement another?
There are eight different nodes for the eight primitive data types (boolean, int, long, byte, short, double, float, and char). These are called BooleanNode, IntNode, and so on. There is one more class simply called Node, which will be discussed in Chapter 5. The data type in the Node class is Java's Object type. So there are nine different nodes in all. If you implement one of these nine node types, implementing another one takes little work: just change the type of the data and the type of any method parameters that refer to the data.
Why does a post fix evaluation algorithm need only one stack?
There is no need for a second stack of opera- tion symbols because each operation is used as soon as it is read.
Suppose you have a class called Thermometer. The class has a no- arguments constructor that sets the thermometer's temperature to zero Celsius. There are two modification methods (setCelsius and set- Fahrenheit) to change the temperature by a specified amount. (One method has a parameter in Celsius degrees, and the other has a parameter in Fahrenheit.) There are two accessor methods to get the current tem- perature (getCelsius and getFahrenheit). A thermometer keeps track of only one temperature, but it can be accessed in either Celsius or Fahr- enheit. Write code to create a thermometer, add 10 degrees Celsius to it, and then print the Fahrenheit temperature.
Thermometer t = new Thermometer( ); t.addCelsius(10); System.out.println (t.getFahrenheit( ));
Which methods would need to be altered if you wanted to keep the numbers in order from smallest to largest in the bag's list? Would this allow some other methods to operate more efficiently? 24
These would change: add, addAll, remove, and union. You could then implement a more efficient countOccurrences that stopped when it found a number bigger than the target (but it would still have linear worst time).
Examine the techniques for adding and removing a node at the head. Why are these techniques implemented as static methods rather than ordinary IntNode methods?
They cannot be implemented as ordinary methods of the IntNode class, because they must change the head reference (making it refer to a new node).
Suppose you want to use a bag in which the elements are double numbers instead of integers. How would you do this?
Use DoubleNode instead of IntNode. There are a few other changes, such as changing some parameters from int to double.
Suppose head is a head reference for a linked list of integers. Write a few lines of code that will remove the second node of the list. (If the list originally had only one node, then remove that node instead; if it had no nodes, then leave the list empty.)
Using techniques from Section 4.2: if (head != null) { if (head.getLink( ) == null) head = null; else head.removeNodeAfter( ); }
Describe the steps taken by countOccurrences if the target is not in the bag.
When the target is not in the bag, the first assignment statement to cursor will set it to null. This means that the body of the loop will not execute at all, and the method returns the answer 0.
Suppose locate is a reference to a node in a linked list (and it is not the null reference). Write an assignment statement that will make locate move to the next node in the list. You should write two versions of the assignment—one that can appear in the IntNode class itself and another that can appear outside of the class. What do your assignment statements do if locate was already referring to the last node in the list?
Within the IntNode class, you may write: locate = locate.link; Elsewhere, you must write: locate = locate.getLink( ); If locate is already referring to the last node before the assignment statement, then the assignment will set locate to null.
Design and implement a class called Clock. A Clock object holds one instance of a time such as 9:48 P.M. Have at least these public methods: - A no-arguments constructor that initializes the time to midnight (see page 43 for the discussion of a no-arguments constructor) - A method to explicitly assign a given time (you will have to give some thought to appropriate arguments for this method) - Methods to retrieve information: the current hour, the current minute, and a boolean method that returns true if the time is at or before noon - A method to advance the time forward by a given number of minutes (which could be negative to move the clock backward or positive to move the clock forward)
You'll find part of a solution in Figure13.1 on page 677.
Draw a picture of my bag.data after these statements: IntArrayBag mybag = new IntArrayBag(10); mybag.add(1);mybag.add(2); mybag.addMany(1,3,4); mybag.remove(1);
[4, 2 , 1, 3]
Write a Java expression that will indicate how many elements are in the array b (from the previous exercise).
b.length
Write a Java method called zero_some with one parameter x that is an array of double numbers. The method changes x[0], x[2], x[4], ... , all to zero. If you activate zero_some(a) for an actual array a of length 6, which components of a will be changed to zero?
public void zero_some(int[] x) // Postcondition: Every even-index element // of x has been changed to zero. { int i; for (i = 0; i < x.length; i += 2) x[i] = 0; } After some_zero(a), these elements of a will be zero:a[0], a[2],and a[4].
Suppose head is a head reference for a linked list. Also suppose douglass and adams are two other IntNode variables. Write one assignment statement that will make douglass refer to the first node in the list that contains the number 42. Write a second assignment statement that will make adams refer to the 42nd node of the list. If these nodes don't exist, then the assignments should set the variables to null.
douglass = IntNode.listSearch(head, 42); adams = IntNode.listPosition(head, 42);
Write code that follows these steps:(1)Declare an integer array variable called b; (2) allocate a new array of 1000 integers for b to refer to; and (3) place the numbers 1 through 1000 in the array.
int i; int[ ] b; b = new int[1000]; for (i = 1; i <= 1000; i++) b[i-1] = i;
Redo the preceding exercise with only five elements instead of 1000. Your solution should be just a single Java statement.
int[ ] b = new int[ ] { 1,2,3,4,5 };
Write a method that copies n elements from the front of one integer array to the front of another. The two arrays and the number n are all arguments to the method. Include a precondition/postcondition contract as part of your implementation.
public void copyFront(int[] a, int[] b, int n) // Precondition: a.length and b.length are // both greater than or equal to n. // Postcondition: n integers have been cop- // ied from the front of a to the front of b. {int i; for (i = 0; i < n; i++) b[i] = a[i]; }
Write another node declaration, but this time the data in each node should include both a double number and an integer. (Yes, a node can have many instance variables for data, but each instance variable needs to have a distinct name.)
public class DINode { double d_data; int i_data; DINode link;
Write the start of the class declaration for a node in a linked list. The data in each node is a double number.
public class DoubleNode { double data; DoubleNode link; ...
Write a new bag method that removes all copies of a specified target from a bag (rather than removing just one copy of the target). The return value should be the number of copies of the target that were removed from the bag.
public int removeAll(int target) { int i; int count = 0; i = 0; while (i < manyItems) { if (data[i] == target) { // Delete data[i] by copying // the last element on top of it: manyItems--; data[i]=data[manyItems]; count++; } else i++; } return count; }
Write a variable-arity version of the remove method. The return value is the total number of elements removed from the bag. Your implementation should use the array version of a for-loop from page 111.
public int removeMany(int... targets) { int count = 0; for (int target : targets) count += remove(target); return count; }
Write a static bag method called intersection that creates a new bag from two other bags b1 and b2. The number of copies of an integer x in the new bag will always be the minimum of b1.countOccurrences(x) and b2.countOccurrences(x).
public static IntArrayBag intersection (IntArrayBag b1, IntArrayBag b2) { int i, j; int count; int it; IntArrayBag a; answer = new IntArrayBag; for (i = 0; i < b1.manyItems; i++) { it = b1.data[i]; if (a.countOccurrences(it)==0) { count = Math.min( b1.countOccurrences(it), b2.countOccurrences(it) ); for (j = 0; j < count; j++) { a.add(it); } } } return a;
Use the new form of the for-loop to write a method that counts how many times a certain target appears in an integer array.
public static int count (int[ ] a, int target) { int answer = 0; for (int item : a){ // Check whether item is target. if (item == target) answer++; } return answer; }
What technique would you use if a method needs to return more than one IntNode, such as a method that returns both a head and tail reference for a list.
the listCopyWithTail method does exactly this by returning an array with two IntNode components.
