CS140 Midterm Exam - March 11, 2014 Answers and Grading

James S. Plank

Question 1: X Points

Part A: You start at 98, and look at successively higher indices mod 100: 98, 99, 0, 1.

Part B: Now, you start at 98, and add 02, 12, 22 and 32: 98, 99, 2, 5.

Part C: Now, you start at 98, and add 0*21, 1*21, 2*21 and 3*21: 98, 19, 40, 61.

Grading

1 point per answer, with the following caveats:


Question 2: 10 Points

Suppose that the file that implements the methods is imp.cpp, and the file that uses the methods is use.cpp. I need to have a header file that both imp.cpp and use.cpp include using "#include" statements. The header file will define the class. In this definition, the methods will be "public" and the data will be "protected. When I compile the program, I will run g++ on the files imp.cpp and use.cpp. I do not include the header file in my compilation.

Grading

Three points per part. You couldn't say "just use make."


Question 3: 6 Points

When you erase an element from the beginning of a vector, the standard template library does the following (assume the vector is v):

for (i = 0; i < v.size()-1; i++) v[i] = v[i+1];
v.resize(v.size()-1);

The running time complexity if that is linear in the size of the input, which makes this perform very poorly. If you want to delete elements from the beginning of a data structure, you should use a deque, because the deletions take constant time rather than linear time, and you can still access the elements like a vector. Second in preference is a list, which also has constant time access, but now you have to use iterators for access.

Grading

Three points for your explanation, and three points for the alternate data structure. If you said list rather than deque, you lost a point, because a deque lets you access elements like a vector.


Question 4: 9 Points

Straight from the lecture notes on lists:

main()
{
  list <string> l;
  list <string>::iterator lit;
  string s;
 
  while (getline(cin,s)) l.push_front(s);
  for (lit = l.begin(); lit != l.end(); lit++) cout << *lit << endl;
}

You could create the list with push_back() and traverse it with a reverse iterator. That works too.

Grading

This is one where you started with 9 points and we deducted for various things.


Question 5: 12 Points

This is a stringstream question:

main(int argc, char **argv)
{
  istringstream ss;
  double d1, d2;

  if (argc != 3) { cerr << "Bad\n"; exit(1); }

  ss.clear();                 // This is optional.
  ss.str(argv[1]);
  if (!(ss >> d1)) { cerr << "Bad\n"; exit(1); }
  
  ss.clear();
  ss.str(argv[2]);
  if (!(ss >> d2)) { cerr << "Bad\n"; exit(1); }
  
  cout << d1 + d2 << endl;
}

Grading

12 points. Grading is like Question 4.


Question 6: 10 Points

string a(string &s)
{
  int i;
  string rv;

  rv = s;
  for (i = 0; i < rv.size(); i++) {
    if (rv[i] >= 'A' && rv[i] <= 'Z') rv[i] += ('a'-'A');
  }
  return rv;
}

Grading

10 points. Grading is like Question 5.


Question 7: 15 Points

There are plenty of solutions. My solution below takes each word and creates a new word consisting of only the non-vowels. If that word is of size zero, then I simply use the original word.

class WordModifier {
  public:
    vector <string> ModList(vector <string> text);
};

vector <string> WordModifier::ModList(vector <string> text)
{
  vector <string> rv;
  string nw;
  string vowels;
  int i, j;
  char c;

  vowels = "aeiou";

  for (i = 0; i < text.size(); i++) {
    nw = "";
    for (j = 0; j < text[i].size(); j++) {
      c = text[i][j];
      if (vowels.find(c) == string::npos) nw.push_back(c);
    }
    if (nw.size() == 0) {
      rv.push_back(text[i]);
    } else {
      rv.push_back(nw);
    }
  }
  return rv;
}

Grading

10 points. Grading is like Question 6. I took off for using erase(), not just because it makes for an n2 algorithm, but your indices are typically messed up afterward.


Question 8: 12 Points

It's best to look at pictures -- a and b hold ints, c and d hold pointers to ints. After the first two statements, we have set a to 22 and c so that it points to a:

In the next two statements, we set b to *c, which is 22. Then we increment a by 10. This is what the variables look like:

So the first three cout statements are:

A: 32
B: 22
*C: 32

Now, in the next four statements, we set c to a newly allocated four bytes, and then set them to 88. We set d to point to the memory to which c points, and then we set a to equal what *c, which is 88. Here are the variables:

Now, we set *c to 77, which changes those four bytes. a remains at 88, so when we set b to a, it is 88. Then incrementing it by five yields 93. Here is the final state of the variables:

The output is:

A: 88
B: 93
*C: 77
*D: 77

Grading

1.7 points per line, except for the first, which was 1.8. The last line had to equal the penultimate line.