CS307 fall 2009 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. [4, 4, -1] (comma differences and brace differences okay, just need 4, 4, and 1 in that order.) B. 5 C - E. Can be other than valid / invalid. Some way of saying declaration is okay or not. Explanations NOT needed. -1 each part C. 1. invalid 2. valid D. 1. invalid 2. valid E. 1. valid 2. valid F. 4 G. 0 H. 6 12 I. 7 J. 0 0 K. t4's declared type is TotalPoints. The TotalPoints class does not declare a method named win so the compiler does permit the statement t4.win(); (Or words to that effect. Possible -1 if close, but not completely correct.) L. No output due to a ClassCast exception. (Exception or runtime error acceptable as well. No credit for syntax error or just error.) M. The statement w7.wins *= 2; attempts to access a private instance variable outside the class. N. false O. 0 [5, 3, 0] (comma differences and brace differences okay.) 2. This was an meant to be an easy question. The only real complexity was making checking the bounds on the other IntList. Some mistakes made on accessing other's native array of ints other[index] is wrong. other.container[index] is correct and okay since we are in the IntList class we have access to all IntLists' private instance variables whether they are the calling object or not. (This was mentioned in the question.) Suggested Solution: public void increaseRange(IntList other, int start, int stop){ int index = start; while(index <= stop && index < other.size()){ container[index] += other.container[index]; index++; } } Grading Criteria: 10 points loop through correct elements: attempt: 2 points correct: 4 points (must range check on stop and size of other list. Possible to lose partial points.) Increment elements in this IntList by corresponding values in other IntList. attempt: 1 point correct: 3 points (Must access other.container[index] NOT other[index]. -2 if that mistake is made.) 3A Agian, not terribly difficult. Column counter had to be out loop. Biggest problem was not terminating check in a row when first non zero found. Suggested Solution: private boolean[]findColumnsWithAllZeros(){ boolean[] result = new boolean[coeffs[0].length]; for(int col = 0; col < result.length; col++){ int row = 0; boolean allZeros = true; while(row < coeffs.length && allZeros){ allZeros = coeffs[row][col] == 0; row++; } result[col] = allZeros; } return result; } Grading Criteria: 15 points - create boolean array: 2 points - nested loop with columns first: 3 points - loop through all columns: attempt: 1 point correct: 1 points - loop through rows in a column attempt: 1 point correct: 1 points -stop checking values in column as soon as first non zero found: 3 points - set array value to correct result: 2 point - return result: 1 point 3B Fairly difficult. Had to count up how many columns in new matrix. Since the MathMAtrix never has extra capcity if any rows had to be removed a whole new 2d array needed to be created. It is impossible to null out a column so the element by element copying was necessary. Also lots of problems on determining number of columns in new 2d array of ints. (Should be equal to number of falses not number of trues.) Also some difficulty in tracking index of column in temp and index of column in coeffs, the old 2d array of ints. Also points were not taken off, but when coding be careful about making repeated calls to methods that takle a lot of time like findColumnsWithAllZeros. I saw lots of soluytions that were O(N^3) instead of O(N^2) because of casual calls to findColumnsWithAllZeros. Suggested Solution: public void removeColumsnWithAllZeros(){ int numNewCols = 0; // only one call to findColumnsWithAllZeros for(boolean b : findColumnsWithAllZeros() ) if(!b) numNewCols++; // do any columns need to be removed? if(numNewCols < coeffs[0].length){ int[][] temp = new int[coeffs.length][numNewCols]; int oldCol = 0; for(int col = 0; col < temp[0].length; col++){ if(!allZeros[oldCol]){ // copy column from old coeffs to temp for(int row = 0; row < temp.length; row++) temp[row][col] = coeffs[row][oldCol]; oldCol++; } } coeffs = temp; } } Grading criteria: 15 points get array of booleans from method in part A: 1 point determine number of columns in new 2d array attempt: 2 points create new 2d array of correct size to store values: 2 points nested loop structure to copy values: 2 points copy values from old 2d array to new 2d array: attempt: 2 points correct: 4 points (must keep track of column in old matrix correctly or -3) assign coeffs to refer to new 2d array: 2 points 4A Comments. Very similar to what we did in class. I didn't grade a lot of these. Of those I did grade the biggest problem was not knowing how to call static methdos in the Character class. Character.isUpperCase(ch) FYI in the database of names 'a' is the most frequently used character and 'q' is the least frequently used and there were about 15 names that had both. Suggested Solution private int[] createFreqMapOfLetters(){ int[] freqs = new int[26]; for(NameRecord r : namesList){ String name = r.getName(); for(int i = 0; i < name.length(); i++){ char ch = name.charAt(i); if( Character.isLetter(ch) ){ ch = Character.toLowerCase(ch); freqs[ch - 'a']++; } } } return freqs; } Grading criteria: 15 points: create array of ints size 26: 2 points loop through all elements of nameList: 2 points get String from nameRecord: 2 points loop through all characters in String: 2 points check if character is letter: 2 points if letter convert to lower case and increment correct element in array: 4 return result: 1 point 4B Hardest question on the test. Had to find min and max and then get down into the names and check if both present. Problems included bad initializtion of min and max, getting confused between index into frequency array and value in frequency array, getting name from NameRecord. A number of people went through the name character by character instead of using indexOf. (This was okay, but I think it was more code to write and easier to make a mistake.) Suggested Solution public ArrayList namesWithMostAndLeastUsedLetter(){ ArrayList result = new ArrayList(); int[] freqs = createFreqMapOfLetters(); int indexMax = 0; int indexMin = 0; // find min and max for(int i = 1; i < freqs.length; i++){ if(freqs[i] < freqs[indexMin]) indexMin = i; else if(freqs[i] > freqs[indexMax]) indexMax = i; } char lowerMost = (char)(indexMax + 'a'); char upperMost = Character.toUpperCase(lowerMost); char lowerLeast = (char)(indexMin + 'a'); char upperLeast = Character.toUpperCase(lowerLeast); // search nameList for(NameRecord r : namesList){ String name = r.getName(); if( (name.indexOf(lowerMost) != -1 || name.indexOf(upperMost) != -1) && (name.indexOf(lowerLeast) != -1 || name.indexOf(upperLeast) != -1)) result.add(name); } return result; } Grading criteria: 15 points: - get freq map from part A: 1 point - find min and max: attempt: 2 point correct: 2 points - create resulting ArrayList: 2 points - loop through namesList: 1 point - check name to see it it contains least and most used characters: attempt: 2 points correct: 3 points - add to result if contains both: 1 point - return result: 1 point