CS307 Fall 2008 Midterm 1 Solution and Grading Criteria. Grading acronyms ABA - Answer by Accident AIOBE - Array Index out of Bounds Exception may occur BOD - Benefit of the Doubt. Not certain code works, but, can't prove otherwise ECF - Error carried forward. Gacky or Gack - Code very hard to understand even though it works or solution is not elegant. (Generally no points off for this.) GCE - Gross Conceptual Error. Did not answer the question asked or showed fundamental misunderstanding NAP - No answer provided. No answer given on test NN - Not necessary. Code is unneeded. Generally no points off NPE - Null Pointer Exception may occur OBOE - Off by one error. Calculation is off by one. 1. Answer as shown or -2 unless question allows partial credit. No points off for differences in spacing and capitalization. If quotes included, okay. A. 9 B. Yes, an array index out of bounds error would occur when the method tried to access list[2]. (or words to that effect) C. 3 D. 4 E. 18 F. [7, 1, 6] (comma differences and brace differences okay, just need 7 1 and 6 in that order. G - I. Can be other than legal / illegal. Some way of saying declartion is okay or not. G. 1: illegal, 2: legal H. 1: legal, 2: illegal I. 1: legal, 2: illegal J. Syntax error (can't access private data) K. 5 L. Shoes M. 12 N. 25 O. It does not compile because the only consructor in GamePeg implicity tries to call the default constructor in Peg. There is no default constructor in Peg so the class won't compile. (or words to that effect.) 2. Comments: This was meant to be an easy problem, but a lot of students had issues with the abstyraction. An IntList is not an array and an array is not an IntList. Perhaps it is easy to deal use abstractions but not as easy to create them. Some students wrote the add and resize method and used those. Everyone who took this approach got full credit becuase they implemented the methods correctly. Common problems: - Not creating an IntList - Not ensuring the IntList's array is big enough to hold the values of the sub list. There was no guarantee the sublist would be 10 elements or fewer in length - Problems with bounds of loops. Saw a lot of this: for(int i = start; i < num; i++) start might be greater than num. num is the number of elements in the sub list, not the index of the last element. - Not setting the listSize instance variable of the resulting list to the correct value. (num) Suggested Solution: public IntList subList(int start, int num){ assert 0 <= start && start < size() && num > 0 && (start + num) <= size() : "failed precondition"; IntList result = new IntList(); result.container = new int[num]; for(int i = 0; i < num; i++) result.container[i] = container[i + start]; result.listSize = num; return result; } Point breakdown create array to put values in: 1 point, correct size: 2 points copy values from this list to resulting array, attempt: 3 points, correct: 4 points create resulting IntList: 1 point make resulting IntList's container the array that contains the values: 2 points size of reuslting IntList correct: 1 point return result: 1 point (must be an IntList) 3.Comments: Students generallly did well on this problem. There wasn't antyhing terrible tricky other than having to deal with elements that were null and handling the case when there were 0 non null elements in the array. Common problems - not calling isLetterOrDigit correctly. (Character.) - not checking for nulls or mishandling them - doing int division on the result instead of floating point division (it is all based on the operands) - not returning -1 if there were 0 non null elements Suggested Solution: public static double averageLettersAndDigitsPerString(String[] words){ int numChar = 0; int numStrings = 0; for(int i = 0; i < words.length; i++){ if( words[i] != null){ numStrings++; for(int j = 0; j < words[i].length(); j++) if( Character.isLetterOrDigit( words[i].charAt(j))) numChar++; } } double result = -1; if( numStrings > 0 ) result = 1.0 * numChar / numStrings; return result; } Point breakdown loop through array attempt: 2 points, correct: 2 points check for null elements attempt: 2 points, correct: 2 points count strings 2 points loop through characters in String attempt: 1 point, correct: 2 points check if character is letter or digit: 2 points count letters and digits: 2 points result -1 if no strings: 1 point calculate result: 2 points (-1 if int division) 4. Comments: Most students did well on this one. The problem was straigtforward. The trick was to find the zeros and then apply the changes after all the zeros are found OR make a copy of the matrix, make the changes to the copy as you find zeros in the orignal, and then copy element for element back to the original Common problems: - applying 0s too soon. Imagine a matrix with one zero in the upper left corner. If you apply zeros as soon as you find that first 0 you make the whole top row and first column 0s. This leads to the whole matrix being zero. - trying to manipulate pointers instead of copying back to the original, element for element. Suggested Solution: public void applyZeros(int[][] mat){ // should a row or column be set to 0? boolean[] rows = new boolean[mat.length]; boolean[] cols = new boolean[mat[0].length]; // find 0s in mat for(int r = 0; r < mat.length; r++){ for(int c = 0; c < mat[0].length; c++){ if( mat[r][c] == 0 ){ rows[r] = true; cols[0] = true; } } } // change rows to 0 for(int r = 0; r < rows.length; r++){ if( rows[r] ) for(int c = 0; c < mat[0].length; c++) mat[r][c] = 0; } // change cols to 0 for(int c = 0; c < cols.length; c++){ if( cols[c] ) for(int r = 0; r < mat.length; r++) mat[r][c] = 0; } } Points breakdown find 0s: attempt 5 points, correct: 5 points (nested loop) apply 0s: attempt 5 points, correct: 5 points 5. Suggested Solution public class Building{ private int floors; private int feetPerFloor; private int feetOccupied; // pre: fl > 0, fPer > 0, occ <= fl * fPer public Building(int fl, int fPer, int occ){ assert fl > 0 && fPer > 0 && occ <= (fl * fPer); floors = fl; feetPerFloor = fPer; feetOccupied = occ; } // pre: none public double percentOccupied(){ return 1.0 * feetOccupied / (floors * feetPerFloor); } // pre: abs(occ) <= feetOccupied public void changeOccuiped(int occ){ assert Math.abs(Occ) <= feetOccupied; feetOccupied += occ; } } Points breakdown: Class header 1 point (must be public) instance variables 4 points (must be private or lose 1 point) constructor preconditions 1 point constructor header 1 point constructor assert to check preconditions 1 point constructor assignment statements 1 point accessor for percent occupied header correct: 1 point calculation correct 2 points (-1 for int division) mutator for number of square feet occupied (this could be 2 seperate methods) precondition comment: 1 point method header: 1 point method correct: 1 point (okay if no assert)