CS302 Fall 2009 Midterm Exam -- Answers and Grading

James S. Plank. October 13, 2009


Question 1 - 10 Points

Grading is one point per question. If an alternative answer gave you any points, I note it below. Here's a chart of your answers:

a.
O(1)
b.
O(1 - e-λn)
c.
O(n)
d.
O(sqrt(n))
e.
O(en)
f.
O(n2)
g.
O(log2(n))
h.
O(n!)
i.
O(n log2(n))
Activity 1 5 6 2 12 1
Activity 2 14 1 1 10
Activity 3 16 4 6
Activity 4 1 3 1 15 6
Activity 5 22 2 2
Activity 6 1 19 2 4
Activity 7 20 2 1 3
Activity 8 5 18 1 2
Activity 9 8 7 6 5
Activity 10 18 7 1

And a histogram of scores::


Question 2 - 6 Points

This was simple -- just change each vector to a tree and then make sure that no child is greater than a parent. Grading: 1 point per part.

Tree 1: Fine.

Tree 2: No - 26 greater than 37.

Tree 3: Fine.

Tree 4: Fine.

Tree 5: Fine.

Tree 6: No - 19 and 17 greater than 99.


Question 3 - 11 Points

Grading was one point per answer. Grid of answers:

Statement A B C D E F G H I J K
True 17 8 1 23 19 6 16 23 3 26 12
False 9 18 25 3 7 20 10 3 22 14

Histogram of scores:


Question 4 - 12 Points

This is a nuts and bolts map/set program of the type we've gone over multiple times in class. In q4.cpp

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

typedef multiset <string> stringset;

main()
{
  map <int, stringset *> vals;
  map <int, stringset *>::iterator vit;
  stringset *ss;
  stringset::iterator ssit;
  int v;
  string s;

  while (cin >> s >> v) {
    vit = vals.find(v);
    if (vit == vals.end()) vals[v] = new stringset;
    vals[v]->insert(s);
  }

  for (vit = vals.begin(); vit != vals.end(); vit++) {
    ss = vit->second;
    for (ssit = ss->begin(); ssit != ss->end(); ssit++) {
      cout << *ssit << endl;
    }
  }
}

Grading was out of 12 points. If you gave me a program that simply shoved values and names into one map, then traversed and printed it, you received 7 points.


Question 5 -- 12 Points

At a high level, program creates a vector where all the values less than m are in the front of the vector and all the values greater are in the back.

However, the exact order within the vector depends on the input. When a string is greater than or equal to m, it is appended to the vector. When it is less than m, then we traverse the vector to find the first value that is greater than or equal to m, and we append that to the end of the vector, and put the new value in its place.

I've modified program.cpp to print out the state of v after reading each word. The new program is program2.cpp, and the last line of its output is the answer to each part:

UNIX> program2 a < I1.txt
there's 
there's a 
there's a port 
UNIX> program2 m < I1.txt
there's 
a there's 
a there's port 
UNIX> program2 s < I1.txt
there's 
a there's 
a port there's 
UNIX> program2 a < I2.txt
there's 
there's a 
there's a port 
there's a port on 
there's a port on a 
there's a port on a western 
there's a port on a western bay 
UNIX> program2 m < I2.txt
there's 
a there's 
a there's port 
a there's port on 
a a port on there's 
a a port on there's western 
a a bay on there's western port 
UNIX> program2 s < I2.txt
there's 
a there's 
a port there's 
a port on there's 
a port on a there's 
a port on a there's western 
a port on a bay western there's 
UNIX> 
Grading was one point per output.

Part 2

If every string is less than m, we traverse the list in its entirety for each string. That is the sum of all numbers from 1 to n: O(n2). Grading was 2 points for this part.

Part 3

The best thing to do is to use two lists -- one for strings less than m and one for strings greater than or equal to m. Let's name the first list small and the second one big. When we see a string greater than or equal to m, we append it to big. Otherwise, we append it to small, then take the first element of big, delete it, and append it to big.

This is done in q5.cpp. You didn't have to implement it -- the above description would suffice to get a perfect score.

#include <vector>
#include <list>
#include <iostream>
using namespace std;

main(int argc, char **argv)
{
  list <string> big;
  list <string> small;
  list <string>::iterator lit;
  string m;
  string s;
  vector <string> v;
  int i;

  if (argc != 2) { cerr << "usage: program string\n"; exit(1); }
  m = argv[1];

  while (cin >> s) {
    if (s >= m) {
      big.push_back(s);
    } else {
      small.push_back(s);
      lit = big.begin();
      if (lit != big.end()) {
        big.push_back(*lit);
        big.erase(lit);
      }
    }
  }
  for (lit = small.begin(); lit != small.end(); lit++) cout << *lit << " ";
  for (lit = big.begin(); lit != big.end(); lit++) cout << *lit << " ";
  cout << endl;
}

Grading here was out of 4 points.


Question 6 - 6 points

The best thing here is to narrow it down using the first two or three lines, then simply verify that the rest of the lines adhere to the sorting algorithm. Grading was one point per output.


Extra Credit

A classic from 1972: "Brandy (You're a Fine Girl)" by "Looking Glass." One of many great songs where the backup singers earnestly croon "Doo doo-doo doo doo...." Wikipedia tells us (here) that it has been covered both by the Red Hot Chili Peppers and Kenny Chesney. Ewwww.

No one got it right, although as usual, I enjoyed the guesses.