- (14 points) For each of the following questions circle the best answer from the
above list.
Sometimes it may seem as though two or more choices would
be equally good. In those cases think about the operations that the
data structures support and what I said about them in class. Then
choose the data structure whose operations
are best suited for the problem.
You may have to use the same answer for more than one
question.
a. vector (could be multi-dimensional)
b. list
c. deque
d. map
e. set
f. multimap
g. multiset
h. hash table
- a b c d e f g h : You want to keep a collection of appointments keyed by date/time. Assume that you have a way to compare date/times using the relational operators. The number of appointments in the collection is typically greater than 100 and it is important to be able to print the appointments in sorted order and also to access a range of appointments efficiently.
- a b c d e f g h You are keeping a census of the number of people in each state in the US and the states are keyed by the name of the state (i.e., a string). You need to be able to efficiently locate a state and add or subtract from its population count. The states do not need to be kept in sorted order.
- a b c d e f g h You are keeping a census of the number of people in each state in the US and the state names are now an enumerated constant rather than strings. You need to be able to efficiently locate a state and add or subtract from its population count.
- a b c d e f g h An internet router holds a collection of packets that it receives in a queue in which packets are added to the end of the queue when they arrive and removed from the front of the queue when they are dispatched to another router.
- a b c d e f g h A bank keeps a set of transactions for a user. The transactions are ordered by date so there may be multiple transactions on the same date. It should be possible to efficiently add, delete, and find transactions, print out all transactions on a given date, and print out all transactions in a given date range.
- a b c d e f g h The data structure you could use to store the items in a checkout cart for a user at an e-commerce web-site. The items can be in any order. Items are added at the end of the cart but it should be possible to easily delete items from the middle of the cart. Generally there are only a few items in the cart.
- a b c d e f g h The data structure you could use to store the number of times a person has visited a web-site. You want to be able to efficiently find, insert, and delete people. You do not need to keep them in sorted order.
- (9 points) In a calendar app, each date has to store a collection of activities for that day, ordered by the start time of the event, and it has to be possible to efficiently insert, delete, and find activities by their start times. There are three data structures that one might reasonably use to store each collection depending on whether you think most days will have very few activities, a moderate number of activities, or a very large number of activities: a map, a list, and a vector. Each has potential advantages and disadvantages in terms of time and space and each would work better with one of the three expected numbers of activities for each day. For each of the three data structures, indicate 1) what their potential advantage and disadvantage is in terms of time/space and 2) which of the three sizes (low, moderate, or large) would make them the most advantageous data structure to use (also explain why they would be most advantageous in that situation).
- (10 points) In the Processing Coke Codes lab, you had to write a
function where you redeemed a prize for a user and deducted the "cost" of
the prize from the user's points. Here is a snippet of code from that
function that could potentially fail and cause your program to seg fault:
bool Redeem_Prize(const std::string &username, const std::string &prize) {
1) map<string, User *>::iterator userIter = Names.find(username);
2) map<string, Prize *>::iterator prizeIter = Prizes.find(prize);
3) int userPoints = userIter->second->points;
4) int prizePoints = prizeIter->second->points;
5) Prize *prizeRecord;
6) if (userIter == Names.end())
7) return false;
8) if (prizeIter == Prizes.end())
9) return false;
... rest of code for redeeming the prize ...
}
- Which line or lines of code might cause the seg fault?
- In four sentences or less describe why the program could seg fault and
what you can do to fix the problem. I do not want to see code--give me an English language description.
- (8 points) Suppose I have the following declarations:
class PersonNode {
public:
string name;
PersonNode *next;
PersonNode(): next(NULL) {}
PersonNode(string n) : name(n), next(NULL) {}
}
PersonNode *x = new PersonNode();
PersonNode *y = new PersonNode();
PersonNode *newnode = new PersonNode("brad");
x = newnode;
y = x;
The code executes correctly and has the intended effect of making both
x and y point to newnode. Nonetheless there is a problem with this code (it
is not in the class declaration--it is in the four statements that follow it).
- What term is used to describe the problem with the above code?
- Show how you would correct the code (i.e., rewrite the part of the code that is causing the problem).
- (12 points) You are given the following running times for each of the following
algorithms:
- T(n) = 3n3 + 10n + 50;
- T(n) = n3 + 20n2 + 1000;
- T(n) = 2n + 5*nlog n + 30;
- T(n) = 10000000;
- T(n) = 800n + 6000;
- T(n) = 500*log n;
- T(n) = 16(n*log n) + n + 3
- T(n) = 20*(1.6n)
- For each algorithm give its Big-O running time
- As n approaches infinity, order the algorithms from fastest to slowest.
- (9 points) You are given the following partial class declaration:
class House {
protected:
string streetAddress;
string city;
string state;
int zipCode;
public:
1) House(string streetAddr, string city, string state, int zip);
2) House();
3) House(const House &house);
4) ~House();
5) House& operator= (const House &house);
};
For each of the following labeled statements, indicate which of the above five
functions gets called:
int main() {
1) House myHouse("45 Myrtle Lane", "Knoxville", "TN", 37996);
2) House bearHouse(myHouse);
3) House treeHouse = bearHouse;
4) House beeHouse;
House *snailHouse;
5) beeHouse = bearHouse;
6) snailHouse = new House();
7) delete snailHouse;
8) bool result = InspectHouse(myHouse);
9) return 0; // main exits and is popped off the stack
}
bool InspectHouse(House h) {
code to inspect h and return true/false
}
- (10 points) You are given the following recursive function:
int mystery(int n) {
1) if (n == 0) return 5;
2) else if (n == 1) return 1;
3) else if (n == 2) return 4;
4) else if (n%2 == 0) return 2*mystery(n/2);
5) else return mystery(n-3) + 6;
}
int main() {
1) cout << mystery(53) << endl;
}
Show the contents of the stack when mystery(53) is called and finally reaches
its base case. For the final frame (the base case frame), show the line on
which the function returns. Use Dr. Plank's notation for the stack. For example:
[a: line 2, i = 1]
[a: line 4, i = 10]
[main: line 9]
Each stack frame should start with the function name, then
the line at which it made
the call to the next function, and then the values of any parameters and local
variables. In the above example main called a at line 9, a then
recursively called itself from line 4, and the base case of a is
returning on line 2.
- (8 points) Recall the diamond hunt problem from both lab and class:
You are a diamond hunter looking for diamonds in a peculiar mine. This mine is a String of '<' and '>' characters, and each diamond is a substring of the form "<>". Each time you find a diamond, you remove it, add 1 to your diamond count, and update the residual mine by removing the 2 characters from the String.
For example, if you have a mine like "><<><>>><", you can start by removing the first appearance of "<>" to get "><<>>><", then remove the only remaining diamond to get "><>><". Note that this produces a new diamond which you can remove to get ">><". Since there are no diamonds left, your expedition is done and you end up with three diamonds.
Write a recursive definition for this problem by 1) stating the base case, and 2) stating the recursive case. I am not looking for code. I want an English description and in fact you should be able to extract your English descriptions from the above problem description.
- (10 points) Suppose you are given the following code fragment:
list<string> names;
list<string>::iterator nit, nit1;
list<string>::reverse_iterator rnit, rnit1;
names.push_front("hare");
names.push_back("bear");
names.push_back("hound");
names.push_front("hen");
names.push_front("rabbit");
nit = names.begin();
nit++;
nit++;
nit++;
nit = names.insert(nit, "grizzly");
nit--;
nit--;
nit = names.erase(nit);
rnit = names.rbegin();
rnit++;
rnit++;
nit1 = names.end();
rnit1 = names.rbegin();
- Show what the contents of the list looks like after this code fragment
executes. You should not include sentinel nodes.
- Show which animal each of the following iterators points to when the
code fragment finishes executing. If the iterator points to the sentinel
node, then write "sentinel".