Question 1: 13 Points

Since the queue is FIFO, the q.Pop() statement removes Dub from the queue. You are left with a two element queue. I will not explain the structure here. Read the lecture notes on queue implementation for an explanation. Part A:

Part B: To push, you have to do two things, depending on the current size of the queue. If it is zero, then simply create a one-element queue whose first and last pointers point to the only node. Otherwise, you allocate a new node, and have the last element point to it. In either case, you update the size:

void Queue::Push(string s)
{
  Qnode *n;

  n = new Qnode;
  n->s = s;
  n->ptr = NULL;

  if (size == 0) {
    first = n;
  } else {
    last->ptr = n;
  }
  last = n;
  size++;
}

Part C: The easy way is to do a simple loop using Empty() and Pop:

Queue::~Queue()
{
  while (!Empty()) Pop();
}

That only gets you half credit, though, because it is inefficient performance-wise. Instead, start at the first node and traverse to the back, calling delete:

Queue::~Queue()
{
  Qnode *tmp;

  while (first != NULL) {
    tmp = first;
    first = first->ptr;
    delete tmp;
  }
}

Grading


Question 2: 12 Points

Part A: 2439016044 mod 50 equals 44. Therefore, the indices are 44, 45, 46 and 47.

Part B: With quadratic probing, we add i2 to the index for i equals 0, 1, 2 and 3. Therefore, the indices are 44, 45, 48 and 3 (since you have to take the result mod 50).

Part C: With double hashing, we add i*h to the index for i equals 0, 1, 2 and 3, and h equal to the other hash. The other hash in this case is 230264537, which equls 37 mod 50. Therefore, the indices are 44, 81%50 = 31, 118%50 = 18 and 155%50 = 5.

Part D: We perform the same mechanics as in Part C, only now the initial index is 2 and h is 32. Therefore, the indices are 2, 34, 66%50 = 16 and 98%50 = 48.

Grading

Three points for each part.


Question 3: 6 Points

The point of this question was to realize the following:

Grading


Question 4: 8 Points

Since you don't want to strip duplicate lines, you should use a multiset: setsort.cpp

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

main()
{
  multiset <string> l;
  multiset <string>::iterator lit;
  string s;

  while (getline(cin, s)) l.insert(s);
  
  for (lit = l.begin(); lit != l.end(); lit++) cout << *lit << endl;
}

Grading


Question 5: 10 Points

Command A: This sets mod equal to 3. We then have 29%3=2, 45%3=0, 10%3=1, 6%3=0 and 60%3=0. Thus, the map holds the following [key,value] pairs: [0,3], [1,1] and [2,1]. The program prints:

0: 3 -> 1
1: 1 -> 1
2: 1 -> 3

Command B: This sets mod equal to 7. We then have 6%7=6, 5%7=5, 13%7=6, 20%7=6 and 27%7=6. Thus, the map holds the following [key,value] pairs: [5,1], [6,6]. The program prints:

5: 1 -> 4
6: 4 -> 0

Command C: This sets mod equal to 5. We then have 100%5=0, 54%5=4, and 15%5=0. Thus, the map holds the following [key,value] pairs: [0,2], [4,1]. However, when i equals zero in the loop, looking up m[1] to print it out actually inserts it into the map with a value of zero. Therefore, all values of i are printed, between 0 and 4:

0: 2 -> 0
1: 0 -> 0
2: 0 -> 0
3: 0 -> 1
4: 1 -> 2

Grading

There are 10 total lines of output -- each is worth a point.


Question 6: 5 Points

First, if they just had Users in their second field, they would use twice as much memory, because the users would have to be duplicated.

Second, if they just had Users in their second field, then the users in Names would have to be duplicates of those in Phones. Were you to perform an action such as Add_Phone() or Remove_Phone(), it would have to act on both the copy in Names and the copy in Phones (and any other copy that you would have. By storing a pointer, Add_Phone() and Remove_Phone() add or remove a phone from one User, which is pointed to by Names and Phones.

Grading


Question 7: 8 Points

You want to keep a count of the number of each kind of digit that you need, and then you return the maximum count. The problem is that 6 and 9 complicate matters. First, you should use one counter for both. Then, you should account for the fact that two of those digits come in each set. The example, if you have i sixes/nines, then you need (i+1)/2 sets.

The program works as follows -- keep a vector count for the digits, where count[i] is the number of times digit i appears in the number. If i is nine, you add it to count[6].

When you're done, set count[6] to (count[6]+1)/2. Then find the maximum value in count -- that is the number of sets.

Here's the code. I've bundled it up into a program that takes the number on the command line in q7.cpp:

int RoomNumber::numberOfSets(int n)
{
  vector <int> count;
  int i;
  int digit;
  int max;

  count.resize(9, 0);

  while (n > 0) {
    digit = n % 10;
    n /= 10;
    if (digit == 9) digit = 6;
    count[digit]++;
  }

  count[6] = (count[6]+1)/2;
  max = 0;
  for (i = 0; i < 9; i++) if (count[i] > max) max = count[i];
  return max;
}

Grading