CS305j Fall 2007 Midterm 2 Key, Suggested Solutions, and Grading Criteria Abbreviations: NAP - no answer provided ECF - error carried forward OBOE - off by one error BOD - benefit of the doubt GCE - misunderstood question. Answer is way off base. 1. {17} {15, 1, 12} {0, 3, -5, 13, 9, 7} The sample code reverses the elements of the array sent as a parameter. Most students did well on this question. Partial credit available. Some students simply could not determine what the code did. Some confusion of the index of an element in an array and the value in the element itself. 2. Suggested Solution // assume rushYards, passYards, and turnoversRecovered will all be >= 0 public static double expectedPoints(int rushYards, int passYards, int turnoversRecovered, boolean homeGame){ double result = 0.0; result += rushYards / 100.0 * 4; result += passYards / 100.0 * 2; result += turnoversRecovered * 2; if( homeGame ) result += 3; return result; } Points breakdown: calculate points from rushing yards correctly 5 calculate points from rushing yards correctly 4 calculate points from turnovers correctly 4 calculate points from home game yards correctly 5 return result 2 Common errors were not doing floating point division (-2) and not handling fractional points less from rushing or passing yards less than 100(-2). Also saw some answers that mixed up multiplying by 4 or 2. For example result += rushYards / (100.0 * 4); // This divides by 400 There should not have been any output to System.out.println. It was okay to shorten then method such as public static double expectedPoints(int rushYards, int passYards, int turnoversRecovered, boolean homeGame){ double result = 0.0; if( homeGame ) result += 3; return result + (rushYards / 100.0 * 4(passYards / 100.0 * 2) + (turnoversRecovered * 2); } 3. Suggested Solution: public static double diffMinMax(double[] values){ double min = values[0]; double max = values[0]; for(int i = 1; i < values.length; i++){ if( values[i] < min) min = values[i]; else if( values[i] > max ) max = values[i]; } return max - min; } This should have been a simple problem searching the array for the min and max value. We did a similar exercise in class for finding the min when demonstrating selection sort and there were javabat problems that would prepare you for this question. Points breakdown: vars for min and max 3 correct initialization of min and max 2 loop through array attempt 2 loop through array correct 5 check for min and max and track attempt 2 check for min and max and track correct 5 return difference correctly 3 The instructions said not to use other methods so Math.min and Math.max were off limits. i wanted to be sure students could write if statements. Some of the common problems were comparisons of values at a given index and the given index + 1. This will find a local min or max, but will not track the overall min or max correctly. Another common problem was initializing min and max to 0 or some arbitrary values instead of the value of the first element of the array. Assigning min or max zero may lead to a logic error. For example, what if everything in the array is bigger than 0? Then you do not find the min correctly. It was okay to have 2 for loops to run through the array, the first one to find the min and the second one to find the max. 4. Suggested Solution public static String removeChars(String org, char[] remove){ String result = ""; boolean found = false; int pos = 0; for(int i = 0; i < org.length(); i++){ pos = 0; found = false; while(!found && pos < remove.length){ found = org.charAt(i) == remove[pos]; pos++; } if( !found ) result += org.charAt(i); } return result; } Points breakdown: create result, initialize as an empty String 2 loop through the characters of the String attempt 2 loop through the characters of the String attempt 3 pull out / examine chars of the String org 2 loop through elements of the array named remove attempt 2 loop through elements of the array named remove correct 3 determine if current character from org is present in array remove attempt 2 determine if current character from org is present in array remove correct 6 add on character to result correctly 2 return resulting String 1 Clearly the hardest question on the test.A nested loop was necessary. The outer loop went through the characters of the String org. The inner loop was needed to check to see if the current character from org was present in the array named remove or not, When that was completed if the character was not present it was addend to the result. Very few students could successfully check to see if the character was present or not. There were a lot of incorrect answers of the following form: public static String removeChars2(String org, char[] remove){ String result = ""; for(int i = 0; i < org.length(); i++){ for(int j = 0; j < remove.length; j++){ if( org.charAt(i) != remove[j]) ) result += org.charAt(i); } } return result; } This adds far to many characters to the result. One for each character in remove that is not equal to the current character. For example the method call removeChars("Hi", {'a', 'b'} ) should return the String "Hi" since no characters are removed. But the incorrect version returns the String "HHii". Some solutions hard coded or assumed the characters in the array named remove were always the same. This violates the whole idea of having a parameter to generalize the problem. There was an interesting solution that didn't use a boolean. public static String removeChars3(String org, char[] remove){ String result = ""; int count; for(int i = 0; i < org.length(); i++){ count = 0; for(int j = 0; j < remove.length; j++) if( org.charAt(i) != remove[j]) count++; if( count == remove.length) result += org.charAt(i); } return result; } 5. Suggested Solution public static int[] removeRange(int[] data, int start, int stop){ int[] result = new int[data.length - (stop - start)]; for(int i = 0; i < start; i++) result[i] = data[i]; int dataIndex = stop; for(int resultIndex = start; resultIndex < result.length; resultIndex++){ result[resultIndex] = data[dataIndex]; dataIndex++; } return result; } The most common correct solution I saw was this: public static int[] removeRange2(int[] data, int start, int stop){ int[] result = new int[data.length - (stop - start)]; int indexInResult = 0; for(int i = 0; i < data.length; i++){ if( i < start || i >= stop ){ result[indexInResult] = data[i]; indexInResult++; } } return result; } The boolean expression on the if could have been !(i >= start && i < stop) which was common as well. Points breakdown: create new, resulting array 3 resulting array is of correct length 2 loop through array named data attempt 2 loop through array named data attempt 3 only copy correct elements into result, attempt 4 only copy correct elements into result, attempt 8 return resulting array 1 This was also a relatively easy problem. The biggest problems I saw were not making the resulting array the correct length, not tracking the index in the result, since elements were in a sense shifted. Another very odd problem was misconception about what to remove. The parameters named start and stop were indices from the original array to exclude, not values. A lot of did not understand this and thought they were to exclude any values from the original array whose elements fell between start and stop. For example if start was 0 and stop was 3 students thought any element whose value was between 0 and 3 should be left out regardless of its index. The examples should have made it clear this was not the case.