2021 COSC 202 Midterm: Answers and Grading Guide
October 12, 2021.
James S. Plank
1-TF: Questions 1 through 12
These were true-false questions from banks. Each was worth 2 points with no partial
credit. Here are answers to the example exam:
- True.
- True.
- False -- it calls the assignment overload.
- True.
- False -- you need to also declare a constructor with no parameters.
- False -- you should throw an exception.
- False -- regardless of whether you use a copy constructor a class will have a default
one defined.
- True -- you lose the pointer on iterations 1 through 4.
- False -- protected means that a method in the class ican call it.
- False -- you can do both. The second one won't be very useful.
- True -- once for x, and five times for the vector.
- No -- its regular constructor will be called five times.
2-V-of-V: Question 13
This came from a bank, where the program was the same, but the inputs were different.
The question in the example yields the following array:
v[0]: 7, 3, 4, 2
v[1]: 1, 9, 8, 6
v[2]: 7, 5
v[3]: 7, 4, 3
|
So the answers were:
Grading: Each part was worth 2.5 points. I assigned the following partial credit:
- Line 2: 1.5 points if you gave me v[0][1].
- Line 3: 1.5 points for v[1][3] or v[3][0]. 1 point for v[0][3]. 0.5 points for v[2][0] or v[0][2].
- Line 4: 1.5 points for v[0][3] or v[3][1]. 1 point for v[3][0] or v[3][2]. 0.5 points for v[2][0] or v[0][2].
3-Hash: Question 14
This came from a bank, where the hash table was shifted one or two places, but the interrelationship
was the same. Here are answers to the
example exam:
- 10/20, 1/2. 0.5, etc.
- 4
- One (I gave full credit to zero): Entry 4 is empty, so we may conclude instantly that
"Frank" is not in the table.
- 6 and 7 are non-empty, so it goes into 8.
- 12 and 13 are non-empty, so it goes into 12+4 = 16.
- 7 is non-empty, so we try 7+1 = 8 which is
is the answer.
Grading: Three points per part.
Partial Credit:
- 2 points for 10/19, 1 point for 5/8.
- 1.5 points if you're off by one or ten.
- No partial credit.
- 0.5 points if you were off by 8.
- 1 point if you were off by 1. 0.5 points if you were off by -14.
- 1 point if you were off by 12.
4-Ptr: Question 15
This came from a bank where the variable names were different and the pictures looked different,
but the interrelationship between the variables is the same.
Here are answers to the example exam:
- H
- K
- D
- B
- A
- I
- x4 -- the integer holding 51 doesn't have a variable, so it has to have been created with new.
- You can make cases for both yes and no here, so everyone got this one correct if they answered
yes or no. The answer
is really yes -- if you resize x1 and then set x6[1], that sets x1[0] to 0. However, I
gave full credit to both answers.
- No. You can set x6[1] after x5 is declared, when its value is uninitialized.
Grading: Subquestions 1-6 were 1.5 points. The rest were 1 each.
When you see the grading for subquestions 1-7, if your answer was "Yes", it means you
got it correct. If your answer was "X-Y", then it means you answered X, and the correct
answer was Y. The following answers got partial credit of 0.5 points:
B-D D-B H-I I-K J-I J-K K-H K-I
5-Exc: Question 16
This one came from a bank, but all of them had the same flow and answers. Here is the
answer to the
example exam:
- The declaration of f in main calls the constructor: A
- The cout prints: F
- Calling proc1 calls the copy constructor: B
- proc1 prints: D
- proc1 throws the string "E", which gets caught in main(). Before that
happens, the destructor is called on f: C
- main() catches the exception and prints s: E
- main() returns, which calls the destructor for f: C
The answer is
Grading: You received one point for each of these:
- Your answer begins with 'A'
- Your answer ends with 'C'
- Your answer contains 'C', 'E' and 'C' in that order.
- Your answer contains 'F', and 'D' in that order.
- Your answer has no 'H' character
- Your answer has no 'G' character
- Your answer contains the string "BD"
- Your answer starts with "AF"
- Your answer starts with "AFBD"
- Your answer ends with "CEC"
6-List: Question 17
First off, zero is an even number. Try Merriam Webster, MathWorld
or Wikipedia.
There were a few ways to do this, with the cleanest being to loop through the vector
by doing "i += 2" and calling push_back() on the list:
list <string> p(const vector <string> &v)
{
list <string> rv;
size_t i;
for (i = 0; i < rv.size(); i += 2) {
rv.push_back(v[i]);
}
return rv;
}
|
Grading: As with most programming questions, I typically start you with 10 points
and make deductions. When your program is too far afield, I typically assign a few points
and grade with "Please see the answer". If that's what you received, it meant that you
answer was too far off, and you should be reading the program above to understand what the
answer should have looked like.
Common deductions. As I mentioned, I was strict. Some of the deductions were not for
correctness, but for logic and readability. You need to remember that others will eventually
read your code, or you will eventually read your code again after a period of time. Your code
should be as clean and readable as possible, and with a simple and straightforward question
like this one, I expected clean and readable code, even on an exam.
All of the following were one point deductions:
- "Unnecessary boolean - (0 % 2) equals 0" -- If you tested whether (0%2) equals 0, you
are showing me that you don't understand the mod operator.
- No return statement.
- No const on your parameter.
- You didn't include element 0.
- Missing a template specification on the return value in the prototype. This is when
you did something like "list proc(const vector <int> &v)"
- "List variable has no type". This is when you did something like this for rv: "list rv".
- Calling erase on the vector. Remember, this is inefficient, and typically you did it
incorrectly.
- const should be before vector.
- Ampersand for the reference parameter is in the wrong place.
- Using append(), which doesn't exist, instead of push_back(). You have had to use push_back() at least 20 times in this class, and I use it all of the time in lectures. You should know
the proper name in C++.
- Using ++2 or ++i++ instead of += 2.
All of the following were two point deductions:
- Using V->lit.
- Weird class definition -- you are simply supposed to define a procedure
- List will be too small.
- List will be too big.
- Pushing empty strings onto the list.
- List is reversed (e.g. called push_front())
- Used a pointer instead of a reference parameter
- Printing the list.
- The parameter is not a vector
- Having a nested loop to do things.
- Parameter is not a reference parameter.
- Extraneous lit++ in the loop.
- For (i = v.size(); i > 0; i--)
- Putting an integer on the list instead of a string.
- Incorrect call to insert -- if you're using insert (which you shouldn't), you should do rv.insert(rv.end(), v[i]).
- Looping from 0 to v.size()/2 and then inserting v[i] instead of v[i*2].
- Converting strings to ints to test even-ness.
- Bad return type (e.g. void proc(...))
- Testing that (i % 2) != 2.
These were larger deductions:
- You resize l to be twice as big as it should be, and you aren't reading elements of v
- This is supposed to be a procedure. There should not be any cin/cout.
- Extraneous loop at the end.
- You need to call push_back or insert to put strings on the list.
- Using a stringstream instead of a list.
- Put all strings onto the list instead of every other one.
- Crazy if statement which will always evaluate to true.
- Extraneous loop inside the main loop.
- Cannot treat a list like a vector (can't index)
- No type specification for the return value.
- You need to traverse the vector, not the list.
- Returns a vector instead of a list.
Question 18
The approach is to build a vector of vectors. Let's call it v. Then:
- V[0] holds strings that start with 'A' through 'G'.
- V[1] holds strings that start with 'H' through 'N'.
- V[2] holds strings that start with 'O' through 'U'.
- V[3] holds strings that start with 'V' through 'Z'.
The best code to do this only uses an if statement to test for throwing the exception.
Otherwise, you can find the proper index with (s[0]-'A')/7. That's the
code below. Only one student gave me this answer. The next best code used an
if statement for each of those cases above. That answer also received full credit.
Here's the best code:
int main()
{
vector < vector <string> > v;
v.resize(4);
string line;
size_t index, j;
while (getline(cin, line)) {
if (line[0] < 'A' || line[0] > 'Z') throw (string) "Bad Line";
index = (line[0] - 'A') / 7;
v[index].push_back(line);
}
for (index = 0; index < v.size(); index++) {
for (j = 0; j < v[index].size(); j++) cout << v[index][j] << endl;
}
return 0;
}
|
Again, if your grade said "Please see the answer", it means that you were too far off, and you
received 0-5 points. If this happpened to you on either question, I believe
you should be programming more. Work on D2 250's from Topcoder -- I have lots
of them (besides the in-lab programs) with annotated solutions: http://web.eecs.utk.edu/~jplank/topcoder-writeups/.
Grading: You typically started with 16 points and received deductions. The
three big ones were:
- Your code ended up simply printing all of the strings in order: 5 points
- You used four vectors: 3 points
- You used a single vector of strings and took four passes through it: 3 points
Here are other common deductions:
- No exception
- Not reading from standard input.
- Testing all characters instead of character 0.
- Trying to erase elements of the vector while doing your four passes.
- Using v[i] without resizing or calling push_back.
- Using OR when you should use AND.
- Using AND when you should use OR.
- Having < and > backward.
- Incorrectly testing for "not an upper-case letter"
- Writing to cerr rather than throwing an exception.
- Catching the exception.
- Calling (cin >> s) rather than getline().
- Getting the eof() logic wrong (you just need to do "while (getline(cin, s))").
- No "main"
- No "return 0" at the end.
- Only testing for < 'A'
- Only testing for > 'Z'.
- Not using 'A', 'Z', etc.
I didn't take off for the following, but I noted them, because they are programming practices
that you should avoid:
- Calling s.clear() before getline(cin, s) is unnecessary.
- The following if statement is unnecessary: "if (s.size() != 0) { for (i = 0; i < s.size(); i++) ...."
- The following eof() and fail() calls are unnecessary: "while (getline(cin, s)) { if (cin.eof()) break; if (cin.fail()) break;"
- In the following, you should simply return (b): "if (b) return true; else return false;"
- Don't call try if you're not catching anything.
- You should use a for loop instead of "i = 0; while (i < s.size()); { ..... ; i++; }"