COMP-202B, Winter 2010, All Sections FINAL EXAM SOLUTIONS SHORT QUESTIONS --------------- 1. a) An off-by-one error occurs when an incorrect loop condition causes the loop body to be executed either one time too few or one time too many. As a result of the loop body not being executed the correct number of times, the program may produce incorrect results or crash, depending on the statements in the loop body. b) A local variable is a variable declared in the body of a method; its purpose is to hold the results of computations made by a method. Memory for a local variable is allocated when the variable is declared, and deallocated when the variable goes out of scope (that is, when the flow of execution of the program reaches the } which marks the end of the block in which the variable was declared). c) Method overloading is a programming language feature which allows the programmer to declare multiple methods with the same name in the same namespace (each class acts as a namespace in Java), as long as the methods' signatures differ; a method's signature consists of its name, as well as the number of parameters it accepts, their types, and the order in which the parameters' types appear in the formal parameter list. The actual version of the method which is called is determined by analyzing the types of the actual parameters passed to the method for the call. d) Garbage collection is a form of automatic memory memory management; when no variable accessible by a program contains the address in memory of an array or object, the memory that the array or object occupies is marked so that when garbage collection takes place, this memory can be deallocated and made available for use to store new objects created by the program. 2. a) If the condition which controls an if statement is true, the statement / block in the if-part of the if-statement will be executed exactly once; control flow will then continue with the first statement after the if-statement. On the other hand, the statement / block in the body of a while statement will execute as long as the condition which controls the while statement evaluates to true, which could be any number of times. b) A class is a blueprint, a model, for how objects which belong to this class look and behave. An object is an entity which looks and behaves according to the blueprint set in the class it belongs. c) Formal parameters are declared in the header of the method; the values that are passed to the method when the latter is called will be copied into these formal parameters. On the other hand, actual parameters are the actual values passed as input to a method during one actual call to this method. 3. The problem lies with the use of the == operator is the line if (wordArray[i] == word) which is found in the countOccurrences() method. Variables whose types are reference types contain the address where the object or array is stored in memory, not the actual array or object itself. Therefore, when used with such variables, the == operator compares the addresses stored in the variables, not the objects stored at those addresses, and evaluates to true if and only if the two addresses are the same. However, two different objects, which are therefore stored at two different addresses, can have the same state; in this case, trying to compare the variables containing the addresses of these objects with the == operator will result in the expression evaluating to false despite the fact that the two objects have the same state. This is what happens in this program. The Strings "legs" whose addresses are stored at positions 1 and 4 of the array of Strings whose address is itself stored in the variable animalism are copies of the String "legs" passed to the countOccurrences() method when it is called in the code fragment; they are not aliases for this object. There are therefore three different String objects in existence representing the word "legs", and all three of these objects are stored at different memory addresses. None of the addresses of String objects stored in the array passed to the countOccurrences() method are equal to the address of the String literal "legs", so when the addresses are compared with the == operator, the expression always evaluates to false in spite of the fact that some of the Strings are copies of the String literal "legs". The value of result is therefore never incremented, and the method returns 0. We can fix this problem by replacing the == operator in the countOccurrences() with a call to the equals() (or equalsIgnoreCase()) method, like this: if (wordArray[i].equals(word)) The equals() method defined in the String class will return true if the two objects are both Strings and represent the same sequence of characters, regardless of whether the target and parameter are aliases for the same object or contain the addresses of two different objects with the same state. 4. 10/8 17/12 3/2 15/9 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 at Fraction.main(Fraction.java:40) LONG QUESTIONS -------------- 5. a) - dollars (instance variable) - cents (instance variable) - d (formal parameter) - c (formal parameter) b) - dollars (instance variable) - cents (instance variable) - totalCents (local variable) - result (local variable) c) - dollars (instance variable) - cents (instance variable) - result (local variable) d) - yourGrandfather (formal parameter) - keyboard (local variable) - amount (local variable) - c (local variable) 6. 1: 1 2: {2, 4} 3: {2, 6} 4: {{2, 8}, {2, 6}} 5: {[L: 15, R: 16], [L: 17, R: 18]} 6: {[L: 11, R: 20], [L: 13, R: 14]} PROGRAMMING QUESTIONS --------------------- 7. a) public class Item { private String description; private int quantity; public Item(String myDescription) { description = myDescription; quantity = 1; } public String getDescription() { return description; } public int getQuantity() { return quantity; } public void setQuantity(int newQuantity) { quantity = newQuantity; } } b) public class Inventory { private Item[] bag; public Inventory(int capacity) { bag = new Item[capacity]; } public int getCapacity() { return bag.length; } public Item getItem(int position) { Item value; if ((position < 0) || (position >= bag.length)) { value = null; } else { value = bag[position]; } return value; } public boolean consumeOne(String itemDescription) { boolean result; int quantity; int i; result = false; i = 0; while ((i < bag.length) && !result) { if (bag[i] != null && itemDescription.equalsIgnoreCase(bag[i].getDescription()) { quantity = bag[position].getQuantity(); if (quantity == 1) { bag[position] = null; } else { bag[position].setQuantity(quantity - 1); } result = true; } else { i = i + 1; } } return result; } } 8. import java.util.ArrayList; public class WordSet { private ArrayList words; public WordSet() { words = new ArrayList(); } public boolean add(String word) { boolean result; result = false; if (word != null && !words.contains(word)) { result = words.add(word); } return result; } public boolean remove(String word) { return words.remove(word); } public boolean isMember(String word) { return words.contains(word); } public int getSize() { return words.size(); } public WordSet computeDifference(WordSet otherSet) { WordSet difference; String word; int size; difference = new WordSet(); size = words.size(); for (int i = 0; i < size; i++) { word = words.get(i); if (!otherSet.isMember(word)) { difference.add(word); } } return difference; } public String toString() { String result; int size; result = "["; size = words.size(); for (int i = 0; i < size; i++) { result = result + words.get(i); if (i < (size - 1)) { result = result + ", "; } } return result + "]"; } } 9. public static void replace(String oldFile, String newFile, char oldChar, char newChar) throws IOException { Scanner reader; PrintStream writer; String line; String newLine; reader = new Scanner(new File(oldFile)); writer = new PrintStream(new File(newFile)); while (reader.hasNextLine()) { line = reader.nextLine(); newLine = line.replace(oldChar, newChar); writer.println(newLine); } reader.close(); writer.close(); }