This page contains solutions to Practice Midterm 3.
Q1) C++ fundamentals and ADTs
one: {0}
fish: {1, 3, 5, 7, 10}
two: {2, 8}
red: {4, 9}
blue: {6}
conc[toLowerCase(word)].add(pos++);
int findPhrase(string phrase, Map<string,Set<int>>& conc) {
Vector<string> words = stringSplit(toLowerCase(phrase), " ");
for (int start: conc[words[0]]) { // foreach possible start pos
int i = 1;
// iterate over words in sequence and match each position
while (i < words.size() && conc[words[i]].contains(start + i)) {
i++;
}
if (i == words.size()) { // found entire phrase
return start;
}
}
return -1;
}
Q2) Code study: ADTs and Big-O
echoVector |
O(N^2) |
echoStack |
O(N) |
echoQueue |
O(N) |
echoSet |
O(NlogN) |
echoVector
v = {1, 3, 2, 5, 3, 6}
echoStack
s = {3, 5, 6, 3, 1, 0}
echoQueue
q = {3, 1, 5, 2, 6, 3}
echoSet
set = {1, 2, 3, 5, 6}
Queue iterate: The changed code goes into an infinite loop when echoing any non-empty queue.
Set iterate: An attempt to add/remove elements while iterating over a collection in for-each loop raises a runtime error.
Q3) Recursion
// return value is the summed area of white rectangles
double recMondrian(double x, double y, double w, double h) {
if (w * h < 500) {
drawRect(x, y, w, h, "grayscale");
return 0;
}
int choice = randomInteger(1, 3);
if (choice == 1) { // split: none
drawRect(x, y, w, h, "white");
return w * h;
} else if (choice == 2) { // split: horiz
return recMondrian(x, y - h/2, w, h/2) + recMondrian(x, y, w, h/2);
} else { // split: vert
return recMondrian(x, y, w/2, h) + recMondrian(x + w/2, y, w/2, h);
}
}
double drawMondrianRect(double x, double y, double w, double h) {
double white = recMondrian(x, y, w, h);
return (100 * white)/(w * h);
}
Q4) Recursive backtracking
Start with template provided by printTotalSpent and make these changes:
- backtrack: stop at first success, prune dead ends, return true/false
- allow choose zero-one-up to N
- decrement inventory on success
- track state using vector index, no copies/edits to vector
There are several possible approaches that can work. The solution below is the one that is most similar to the template.
bool spendAll(double amount, Vector<itemT>& inventory, int index) {
if (amount == 0) { // success
return true;
}
if (amout < 0 || index == inventory.size()) { // failure
return false;
}
itemT cur = inventory[index];
for (int n = 0; n <= cur.count; n++) { // n is number of item put in basket
inventory[index].count -= n; // choose
if (spendAll(amount - n*cur.price, inventory, index + 1)) { // explore
return true; // stop at first success
}
inventory[index].count += n; // unchoose
}
return false;
}
bool spendAll(double amount, Vector<itemT>& inventory) {
return spendAll(amount, inventory, 0);
}