CS140 Midterm 2

Spring 2020

Instructions

  1. Write your name clearly at the top of the exam
  2. You must answer all the questions on the exam. The exam has 9 problems. Make sure that you have all 9 problems.
  3. Write your answers on the exam pages and hand in the exam when you are finished.
  4. You have until the end of the class period to finish the exam. When time is called you must immediately drop your pen/pencil and hand in your exam.
  5. Ensure that you write clearly and legibly and that your diagrams are easy to read. Failure to do so may result in the deduction of points.
  6. The exam is closed note, closed book, closed neighbor.
  7. The total points available for this exam (lab coding questions plus this paper exam) is 150 points. There are 90 points on this exam and there will be 60 points on the coding portion of the exam.
  8. Good luck!

    
    
  1. (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
    

  2. (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).

  3. (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 ...
    }
    1. Which line or lines of code might cause the seg fault?
    2. 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.

  4. (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).
    1. What term is used to describe the problem with the above code?
    2. Show how you would correct the code (i.e., rewrite the part of the code that is causing the problem).

  5. (12 points) You are given the following running times for each of the following algorithms:
    1. T(n) = 3n3 + 10n + 50;
    2. T(n) = n3 + 20n2 + 1000;
    3. T(n) = 2n + 5*nlog n + 30;
    4. T(n) = 10000000;
    5. T(n) = 800n + 6000;
    6. T(n) = 500*log n;
    7. T(n) = 16(n*log n) + n + 3
    8. T(n) = 20*(1.6n)
    1. For each algorithm give its Big-O running time
    2. As n approaches infinity, order the algorithms from fastest to slowest.

  6. (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
    }
  7. (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. (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.

  9. (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();
    
    1. Show what the contents of the list looks like after this code fragment executes. You should not include sentinel nodes.
    2. 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".