## Solutions

1. (5 points) 0x3e9a + 0x4b3 = 0x434d

2. (5 points) Suppose you are given the following code fragment:
```unsigned char h = 23;
h = (h << 2) ^ 0xa6;
```
What is the hexadecimal value of h after the above code executes? The answer is 0xfa.

You will probably need to write everything out in binary to solve this problem.

``` 23  = 0001 0111
23 << 2 = 0101 1100    // 2 leftmost 0's shifted into the bit bucket
0xa6 = 1010 0110

Hence (23 << 2) ^ 0xa6 can be written as:

0101 1100
^ 1010 0110
___________
1111 1010

which is 0xfa.
```

3. (16 points) For each of the following questions circle the best answer from the list.
```
a. vector
b. list
c. deque
d. map
e. set
f. multimap
g. multiset
h. hash table
```

• f The data structure you should use to implement a mail folder that for each email needs to store a key, which is the date (dates might not be unique), and a value, which is a pointer to an object that contains information about the email. The mail in the folder should be ordered in ascending order by date.
• h The data structure you could use to determine whether a phone number is already in use. You need to be able to insert new phone numbers into the data structure and determine whether a phone number is in the data structure. The phone numbers do not need to be ordered.
• a The data structure which allows any of its elements to be accessed in guaranteed constant time.
• b The data structure you would use if you needed to be able to delete an element in the middle of an unordered data structure.
• c The data structure you should use if you wanted to print out the last n lines of a file where n is a command-line argument. You should only hold n lines of the file in memory at any time.
• c The data structure you should use if you want to simulate an unbounded line of customers at a grocery store, where customers are served (i.e., are removed) from the front of the line and customers enter (i.e., are added) at the back of the line.
• d The data structure you should use to store race results that are keyed on finish time and that store a value which is the name of the runner with that finish time. Finish times are unique and the runners should be stored in sorted order based on their finish times.

4. (8 points) Suppose I have the following declarations and code:
```     int a, b;
int *x, *y;
```
Also suppose that the above variables are assigned the following memory addresses:
```     a: 0x1000
b: 0x1004
x: 0x1008
y: 0x100c
```
After the following code sequence executes, what are the values of a, b, x, and y?
```       x = &b;
y = x;
a = 10;
b = 40;
*x = 30;
*y = *x * 3;

a: 10
b: 90
x: 0x1004
y: 0x1004

```

5. (6 points) Memory Leak What term is used to describe the problem with the following code? If you can't think of the term, then for 3 points give a 2 sentence or less answer that describes the problem.
```  int *x;
x = new int;
*x = 40;
x = new int;
*x = 60;
```
The code fails to delete the original heap-allocated piece of memory to which x pointed, and as a result, that piece of memory never gets deleted even though it no longer is accessable because it has no pointers to it.

6. (10 points) Explain what is wrong with the following code segment. Use no more than 3 sentences to describe the problem.
```    map<string, set<string> > friendsMap;
map<string, set<string> >::iterator friends_it;
set<string> friendsSet;
string friend1, friend2;
while (cin >> friend1 >> friend2) {
friends_it = friendsMap.find(friend1);
friendsSet = friends_it->second;
friendsSet.insert(friend2);
}
```
The intent of the above code is to maintain a map keyed by name. For each name we keep track of that person's friends. The above code is supposed to add friend2 to friend1's set of friends. You should assume that the input is error-free. The bold-faced line in the above code creates a copy of the set. The insert on the next line thus inserts into the copy, rather than the original set, and the original set does not get updated as it should.

7. (10 points) Draw a list diagram that shows what the following list looks like pictorially after the following code executes. Make sure that you include sentinel nodes and that you show where each list iterator points. Your diagram should look like the ones in the class notes.
```list<string> names;
list<string>::iterator nit, nit1;
list<string>::reverse_iterator rnit;
names.push_back("joe");
names.push_back("mary");
names.push_front("nancy");
names.push_front("tom");
nit = names.begin();
nit++;
rnit = names.rbegin();
nit1 = names.end();
```
8. (10 points) Assume you have the following code:
```class Person {
public:
string name;
Person *bestFriend;

Person(string n) { name = n; }
};

string names[] = { "mickey", "bugs", "daffy", "winnie" };
vector<Person *> friends;
Person *newPerson;
int i;

for (i = 0; i < 4; i++) {
friends.push_back(new Person(names[i]));
}
for (i = 0; i < 3; i++) {
friends[i]->bestFriend = friends[i+1];
}
friends[3]->bestFriend = friends[2];
```
Draw a diagram that shows the vector, the Person objects that get created, and the objects to which each pointer points.

## Code Questions

1. (10 points--CS140Sp15-Mid2-Vector): Write a function named avgWeight that takes a single argument, which is a vector of pointers to User objects, and returns their average weight as a double.
```double avgWeight(vector<User *> &data) {
int sum = 0;
int i;
for (i = 0; i < data.size(); i++)
sum += data[i]->weight;
return sum / (double)data.size();
}
```
2. (20 points--CS140Sp15-Mid2-List): Write a void function named CreateList. CreateList takes three arguments. The first two arguments are an STL list L of strings and a vector V of integers containing integer indices sorted in ascending order. The third argument is an empty STL list NewL of strings. createList(L, V, NewL) will copy into newL the strings from L that correspond to the positions specified by V.

Since the vector contains the elements you want is given to you in ascending order, you only need to make 1 pass through the list. For example, if the vector contains the elements {1, 3, 4, 6}, then you can count to 1 and add the element at location 1 in sourceList to newList. There is no need to reset the count to 0. Instead continue counting to 3, while incrementing the list iterator at the same time, and add the element at location 3 in sourceList to newList. Continue this algorithm until you have added all the requested items from sourceList to newList.

```void createList(list<string> &sourceList, list<string> &newList, vector<int> &elements) {
list<string>::iterator lit;
int i = 0;
int count = 0;

newList.clear();
lit = sourceList.begin();
for (i = 0; i < elements.size(); i++) {
for ( ; count < elements[i]; count++)
lit++;
newList.push_back(*lit);
}
}
```
3. (20 points--CS140Sp15-Mid2-Vote) Write a program that counts the ballots cast for different candidates and then prints out the candidates in alphabetical order and the votes cast for each candidate. The input will be read from stdin. Each line of input will consist of the name of a voter and the candidate for whom the voter is voting. Both the voter and candidate names will be a single word. Your program should verify that the voter has not already voted. If the voter has already voted, then you should ignore the voter's vote. If the voter has not voted, then you should set the candidate's votes to 1 if the candidate does not yet exist or else add 1 to the candidate's number of votes if the candidate does exist. Once the input is exhausted, you should print the candidates and their votes in alphabetical order by candidate.

Either of the following 2 solutions work. The second solution relies on the fact that if you treat the map like an associative map and the candidate is not already in the map, then it will be added to the map and assigned an initial value of 0.

## Solution 1

```#include <iostream>
#include <map>
#include <set>
using namespace std;

int main() {
set<string> voters;
map<string, int> candidates;
map<string, int>::iterator cit;
string voter, candidate;

while (cin >> voter >> candidate) {
if (voters.find(voter) == voters.end()) {
voters.insert(voter);
cit = candidates.find(candidate);
if (cit == candidates.end())
candidates.insert(make_pair(candidate, 1));
else
cit->second++;
}
}
for (cit = candidates.begin(); cit != candidates.end(); cit++)
printf("%-20s %4d\n", cit->first.c_str(), cit->second);
}
```

## Solution 2

```#include <iostream>
#include <map>
#include <set>
using namespace std;

int main() {
set<string> voters;
map<string, int> candidates;
map<string, int>::iterator cit;
string voter, candidate;

while (cin >> voter >> candidate) {
if (voters.find(voter) == voters.end()) {
voters.insert(voter);
candidates[candidate]++;
}
}
for (cit = candidates.begin(); cit != candidates.end(); cit++)
printf("%-20s %4d\n", cit->first.c_str(), cit->second);
}
```