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.