CS140 Final

Spring 2015

Instructions

  1. Use the Code Assessor development website, cs102dev.eecs.utk.edu, to answer each of the coding questions.
  2. Leave this worksheet next to your computer for the next lab section.
  3. You may have a one page cheat sheet, with writing on front and back.
  4. The name of the coding question on Code Assessor is shown next to each question.
  5. The total points available for this exam (the lab coding questions plus the paper exam) is 120 points. You will be graded out of 100 however, so in effect you have 20 extra credit points to work with.
  6. You may not be able to finish all the problems. If so, please do not worry. We will examine all answers (even correct ones) and award partial credit.
  7. We will look at coding style and efficiency in grading your problems. Even if your answer passes the test cases, you might lose points if your solution is overly inefficient, is hard to read, uses poor variable names, etc.
  8. You have the entire lab period. You may leave when you are finished. Please do not discuss the exam with anyone from another lab section until after 2:30pm.
  9. Good luck!

  1. (10 points--CS140Sp15-Final-Recursion): Write a recursive function named palindrome that determines if a string is a palindrome, that is, it is equal to its reverse. For example, "racecar", "g", and "tattarrattat" are palindromes. The function should return a bool with true indicating that the designated portion of the string is a palindrome and false otherwise.

    Parameters(string s, int begin, int end)

    1. s: the string being tested to determine if it is a palindrome
    2. begin: the index of the first character in the string where we should start the testing.
    3. end: the index of the last character in the string where we should end the testing.

    As an example, palindrome("racecar", 1, 5) would return true if "aceca" is a palindrome, since testing should start at index 1 and end at index 5.

    Constraints:

    1. The string is guaranteed to contain at least one character
    2. Any one character string is a palindrome
    3. Any function call in which begin is greater than end should return true
    4. The arguments to the initial call to palindrome will be the string, a beginning index of 0, and an ending index that points to the last character of the string. For example, a call to palindrome with "racecar" might be:
      palindrome("racecar", 0, 6)
      
      Subsequent recursive calls to palindrome may choose to increment/decrement the beginning and ending indices.

    Test Input: The input consists of a single word. For example:

    racecar       palindrome should return true
    
    smiley        palindrome should return false
    
    tattarrattat  palindrome should return true
    
    brad          palindrome should return false
    

  2. (20 points--CS140Sp15-Final-Tree): Write a recursive method named recursive_size that takes a binary tree node as a parameter and returns the number of nodes in the binary search tree rooted at that node. recursive_size should return 0 if the node is a sentinel node and otherwise should return the sum of the number of nodes in the left and right subtrees, plus 1 for the node itself. For example, if the left subtree has 8 nodes and the right subtree has 15 nodes, then recursive_size should return 24. If the node is a leaf node, then each of its children will be a sentinel node and hence the sizes of its two subtrees will each be 0, and recursive_size will return 1. For this problem, you are given the following abbreviated class declaration from the class notes:
    class BSTNode {
      public:
        BSTNode *left;
        BSTNode *right;
        BSTNode *parent;
        string key;
    };
    
    class BSTree {
      public:
        BSTree();
        int Insert(string key);
        int Size();
      protected:
        BSTNode *sentinel;
    
        int recursive_size(BSTNode *n);
    };
    
    int BSTree::Size() {
      return recursive_size(sentinel->right);
    }
    
    Size() passes the root node of the tree to recursive_size. The constructor function initializes the tree and the insert function adds keys to the tree. We have provided the code for the constructor, Size, and Insert functions for you. You only have to write recursive_size.

    Constraints

    1. You will always be passed a pointer to the node of a well-formed binary search tree. That means that if a node does not have a left or right child, then the left or right pointer points to the sentinel node.

    2. The tree is allowed to be empty, in which case the root of the tree will be the sentinel node and recursive_size should return 0.

    Test Input: We have provided a main function that reads two types of commands from standard input:

    1. insert key: inserts a key into the tree
    2. size: prints the size of the tree by calling the tree's Size method and printing the return value. Note that recursive_size should not print anything.

    For example, the input:

    insert joe
    insert mary
    insert brad
    size
    insert frank
    insert jessie
    insert norman
    insert jim
    size
    insert ebby
    insert nancy
    size
    
    should produce the output:
    3
    7
    9
    

  3. (20 points--CS140Sp15-Final-Queue) Write a method named Delete for the singly linked Queue class presented in class lecture notes. Delete takes a string and deletes the node from the queue that contains this string. Delete should return true if the string is in the Queue and false if string is not in the queue. If the key is in the Queue, then Delete should delete its node, make the node preceding the deleted node point to the node succeeding the deleted node, and update the first and last pointers in the queue. For example, if you have the queue:

    and you delete "Caleb", then the queue should become:

    You should use the singly-linked queue structure from the lecture notes. Here is a simplified version of the queue structure:

    class Qnode {
      public:
        string s;
        Qnode *next;
    };
    
    class Queue {
      public:
        Queue();
        void Push(string s);
        bool Delete(string s);
        void Print();
    
      protected:
        Qnode *first;  // points to the first queue node
        Qnode *last;   // points to the last queue node
    };
    
    We have provided the code for the constructor, Push and Print.

    Constraints

    1. first must always point to the first element of the queue. If the queue is empty, then first should be NULL.
    2. last must always point to the last element of the queue. If the queue is empty, then last should be NULL.
    3. If the queue contains a single node, then first and last should both point to this node.
    4. The next pointer for the last node in the list should be NULL. For example, in the above list, "Kayla"'s next pointer should be NULL.
    5. Make sure that your code properly handles the case where the deleted node is either the first or last node in the list. In this case you must ensure that the first and last pointers get appropriately updated.
    6. The keys in the queue will be unique.
    7. Do not print anything. Our test driver does all necessary printing.

    Test Input: We have provided a main function that takes two types of commands:

    1. push key: adds the key at the end of the queue.
    2. delete key: deletes the key from the queue. main prints whether or not the delete succeeded, and if the delete succeeds, then it prints the queue's new contents.
    For example, the input:
    push Mary
    push Frank
    push Caleb
    push Clara
    push Nancy
    push Kayla
    delete Caleb
    delete Mary
    delete Kayla
    delete Chuck
    
    should produce the output:
    delete of Caleb succeeded
    queue is now
    Mary
    Frank
    Clara
    Nancy
    Kayla
    
    delete of Mary succeeded
    queue is now
    Frank
    Clara
    Nancy
    Kayla
    
    delete of Kayla succeeded
    queue is now
    Frank
    Clara
    Nancy
    
    delete of Chuck failed