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)