14
CSC 112 – Final Exam Name: KEY Show all your work and reasoning for your answer in the space provided. Be certain you clearly indicate your final answer. This exam is to be done individually according to the honor code at Wake Forest University Problem 1. This problem has two parts and deals with merge sort. The code for merge sort is available on the last page of the test. 1a) Given the array below, demonstrate your understanding of merge sort You need to show: - the sub-arrays resulting from each level of merging - for the last level of merging, record in a table on the right side of your answer sheet all pairs of values that i and j take on together (the initial pair being i = 0, j = the numerical value of middle+1) Array: [ 3 | 12 | 7 | 4 | 5 | 2 | 9 | 10 | -1 ] The splits would work as follows: [3 | 12 | 7 | 4 | 5] [2 | 9| 10| -1] [3 | 12 | 7] [4 | 5] [2 |9] [10 | -1] [3 | 12] [7] [4] [5] [2] [9] [10] [-1] [3] [12] [7] [4] [5] [2] [9] [10] [-1] They would merge in the reverse order (3 and 12 first, since they were the last broken). [3 | 12] [7] [4] [5] [2] [9] [10] [-1] [3 | 7 | 12] [4 | 5] [2 | 9] [-1 | 10] [3 | 4 | 5 | 7 | 12] [-1 | 2 | 9 | 10] [-1 | 2 | 3 | 4 | 5 | 7 | 9 | 10 | 12] The i,j pairings are for the last stage of merging, starting with: [3 | 4 | 5 | 7 | 12] [-1 | 2 | 9 | 10] i=0 j=5 The (i,j) pairs I got were 0,5 ; 0,6; 0, 7; 1, 7; 2, 7; 3, 7; 4, 7; 4, 8

CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

  • Upload
    lexuyen

  • View
    229

  • Download
    0

Embed Size (px)

Citation preview

Page 1: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

CSC 112 – Final Exam  Name:     KEY  Show all your work and reasoning for your answer in the space provided. Be certain you clearly indicate your final answer. This exam is to be done individually according to the honor code at Wake Forest University Problem 1. This problem has two parts and deals with merge sort. The code for merge sort is available on the last page of the test. 1a) Given the array below, demonstrate your understanding of merge sort You need to show:

- the sub-arrays resulting from each level of merging - for the last level of merging, record in a table on the right side of your

answer sheet all pairs of values that i and j take on together (the initial pair being i = 0, j = the numerical value of middle+1)

Array: [ 3 | 12 | 7 | 4 | 5 | 2 | 9 | 10 | -1 ] The splits would work as follows: [3 | 12 | 7 | 4 | 5] [2 | 9| 10| -1] [3 | 12 | 7] [4 | 5] [2 |9] [10 | -1] [3 | 12] [7] [4] [5] [2] [9] [10] [-1] [3] [12] [7] [4] [5] [2] [9] [10] [-1] They would merge in the reverse order (3 and 12 first, since they were the last broken). [3 | 12] [7] [4] [5] [2] [9] [10] [-1] [3 | 7 | 12] [4 | 5] [2 | 9] [-1 | 10] [3 | 4 | 5 | 7 | 12] [-1 | 2 | 9 | 10] [-1 | 2 | 3 | 4 | 5 | 7 | 9 | 10 | 12] The i,j pairings are for the last stage of merging, starting with: [3 | 4 | 5 | 7 | 12] [-1 | 2 | 9 | 10] i=0 j=5 The (i,j) pairs I got were 0,5 ; 0,6; 0, 7; 1, 7; 2, 7; 3, 7; 4, 7; 4, 8

Page 2: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

1b) The code for merge sort, as written on this test, indicates certain operators need to be defined for a type for merge sort to work correctly with that type. If we were writing our own class and we wanted to be able to store variables of our class type in an array and employ merge sort on our variables, which operators would we have to overload for our class and why? According to the merge sort code provided on the test, the only two operators required are = (assignment) - used in copying data between arrays, such as tempArray[i] = array[i] or array[k++] = tempArray[i++] <= (less than or equal) - used in testing array entries relationships, such as in if (tempArray[i] <= tempArray[j]) Problem 2. This problem deals with recursion and Linked Lists and has 2 parts. 2a) I argue that the LinkedList data-structure is a “naturally recursive” data-structure. Support my argument by discussing a) your understanding of the underlying structure of LinkedLists and b) why this structure is amenable to recursion. Understanding of structure: A LinkedList is basically a chain of nodes – there is a pointer to the 1st node (called the head pointer) and then each node contains a piece of data and a pointer to the following node. The last node has a NULL pointer indicating there is not a node behind it. Why structure amenable to recursion: Consider the first node as an element. The rest of the nodes (behind the first node) could be considered as another linked list, in that they have a pointer to them (first node-> next) and then they are still just a chain of nodes. Recursion employs the notion of solving the same problem, but in a smaller size. Given a linked list, we could work on the first element alone, and then call our method on the “smaller” linked list sitting behind the head element. There is also a natural base case – when the pointer to the list is NULL.

Page 3: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

2b) Assume you are writing a standard head pointer-based LinkedList holding strings like you did in Lab 11. Fill in the recursive count method below whose job is to return the number of times a string of interest passed in as a parameter appears in the container. The initial structure I have set up below should suggest something about how the recursion should be defined. Assume your LinkedList class has been declared a friend of the Node class so you can directly access Node data and next as needed. int LinkedList::count(const string & stringOfInterest) { return countHelper(stringOfInterest, head); } // add parameters as necessary int LinkedList::countHelper(const string & stringOfInterest, Node* theNode) { if (theNode == NULL) return 0; else { If (theNode->data == stringOfInterest)

return 1+ countHelper(stringOfInterest, theNode->next);

else return countHelper(stringOfInterest, theNode->next);

} } Problem 3. This problem deals with insertion sort and has two parts. On the next to last page of the test, you will find the code for the insertion sort algorithm. 3a) We discussed in class that the insertion sort algorithm was O(n) in the best case and O(n2) in the worst case, where n is the number of elements in the array. By reviewing the insertion sort code, what is the initial ordering of data that provides the best case costs for insertion sort and what is the initial ordering of the data that provides the worst case costs for insertion sort? Best case initial ordering: ASCENDING (ALREADY SORTED) - elements don’t move forwards at all. Worst case initial ordering: DESCENDING (REVERSE SORTED) – elements have to move from back all the way to front

Page 4: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

3b) I have in my mind an idea related to insertion sort I want to use for LinkedLists. In addition to insertFront, insertBack, and insertAtPosition methods, I would like to have an insertSorted method. Assume I am using a standard head-pointer, singly-linked LinkedList (like you wrote in Lab 11). The insertSorted method should insert an item into the LinkedList such that, given that the LinkedList is in ascending order before the insert, the LinkedList remains in ascending order after the insert with the new data added at the right place. We have discussed that a down-side to using LinkedLists is the access time to get to some positions in the list. I am curious : given the description of the insertedSorted method above and your understanding of standard head-pointer based, singly linked LinkedLists, what ordering of data being inserted into the list will lead to the worst case traversal cost and what ordering of data being inserted into the list will lead to the best case traversal cost? Justify your answers. Best case initial ordering: DESCENDING (REVERSE SORTED) Worst case initial ordering: ASCENDING (ALREADY SORTED) Justification of choices for (3b) answers: The reading of this problem indicates that insertSorted puts one item into the list at a time (it is a function that is equivalent to insertFront, insertBack, …). It just has to put the item in an appropriate spot given the ordering of the other items already in the list. It also says to use our standard Linked List as we saw in class, meaning we only have a head pointer retained across any function call. If you had a descending set of data (5, 4, 3, 2, 1) to put in the linked list, then any new item being inserted into the list would go at the front of the list (4 in front of 5, 3 in front of 4 and 5, …). This requires no traversals at all as all adds are at the head. If you had an ascending set of data (1, 2, 3, 4, 5) to put in the linked list, then any new item being inserted into the list would belong at the back of the list. Since this is a head pointer, singly linked list, you would have to traverse to the back every time. This requires a lot of traversals (traversing over O(n^2) nodes to be exact).

Page 5: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

Problem 4. Below you will find a program which uses a recursive function to determine if a specific value is in an array. bool findInArray(int* arrayArg, int sizeArg, const int & valueArg) {

bool findAnswer; if (sizeArg == 1)

findAnswer = (*arrayArg == valueArg); else {

if (*arrayArg == valueArg) findAnswer = true;

else findAnswer = findInArray(arrayArg+1,

sizeArg-1, valueArg); }

return findAnswer; } int main(int argc, char* argv[]) {

int* array = new int[3]; array[0] = 1; array[1] = 5; array[2] = 7; int valueToSearchFor = 10; bool answer = findInArray(array, 3, valueToSearchFor);

} Draw the state of the heap and of the function call stack just before the recursion returns from hitting the base case for this problem. As in Test 1, indicate where each variable that is currently ‘alive’ (active in any function) resides and what its value is. If a variable is a pointer type, its value should be represented by an arrow to the memory location it is pointing to; otherwise, use an appropriate integer or Boolean (true/false) value. Please write your answer on the next page, which has purposely been left blank.

Page 6: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

3 instances of findInArray, base case is when sizeArg == 1 findAnswer variable has only been given a value for base case (top of stack) as question says it is just about to return from that case. arrayArg points to specific parts of array as we are manipulating the pointer array is in the heap valueArg is a pass-by-reference pointer, so it needs to point back to original data (implicitly handled by system) sizeArg is passed by value and updated with each call

Page 7: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

Problem 5. Given the description/definition of a class below, implement the following methods appropriately for the class: Must implement: copy constructor Also implement: 1 of either destructor or insertion (output) operator

The class of interest is a TwoLevelImageBuffer class. Often times a tool that is displaying images as an animation will load the next image in memory off of some disk while the current image is still being displayed on the screen. This allow for a quick switch to showing the next image instead of having to pause between images to load (allowing for better looking animation). When a user constructs a TwoLevelImageBuffer using the constructor, the values for height and width specified by the user are stored in integer class variables, a height by width by 2 integer array class variable is allocated (dynamically as appropriate) and an integer class variable indicating which buffer (0 or 1) is the “current buffer to display” is set to 0. If you write the output operator, assume it should display only the contents of the “current buffer to display” level to the screen in a reasonable fashion. Here’s an example of a TwoLevelImageBuffer to help you think about it conceptually:

Please write your answers on the next page, which has been purposefully left blank.

Page 8: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

Must implement: copy constructor Also implement: 1 of either destructor or insertion (output) operator Copy constructor: TwoLevelImageBuffer:: TwoLevelImageBuffer (const TwoLevelImageBuffer & other) {

height = other.height; width = other.width; currentBuffer = other.currentBuffer;

// allocate my own array, which is 3d, and copy the data over // I made the first dimension be size 2, to go to one image or the other // after that, it's a height x width matrix theArray = new int**[2]; for (int j = 0; j < 2; j++) { theArray[j] = new int*[height]; for (int k = 0; k < height;k++) { theArray[j][k] = new int[width]; for (int l = 0; l < width; l++) { theArray[j][k][l] = other.theArray[j][k][l]; } } } } Destructor: TwoLevelImageBuffer::~ TwoLevelImageBuffer () { for (int j = 0; j < 2; j++) { for (int k = 0; k < height;k++) { delete [ ] theArray[j][k]; } delete [ ] the Array[j]; } delete [] theArray; }

Page 9: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

Insertion (output) operator: ostream& operator<<(ostream & out, const TwoLevelImageBuffer & toPrint) { for (int j = 0; j < toPrint.height; j++) { for (int k = 0; k < toPrint.width; k++) {

out << toPrint.theArray[toPrint.currentBuffer][j][k]; } out << endl; }

return out; }

Page 10: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

Problem 6. A graph represents a set of objects and links (relationships) between those objects. The example graph shown below indicates that there are six objects (circles labeled 0-5) and seven links (blue lines) between pairs of objects.

A typical representation of a graph as a data structure involves a integer 2-d matrix called the adjacency matrix (1 link present, 0 link not present). This is the adjacency matrix for the graph above. Object 0 Object 1 Object 2 Object 3 Object 4 Object 5 Object 0 0 1 0 1 1 0 Object 1 1 0 0 0 0 0 Object 2 0 0 0 1 0 0 Object 3 1 0 1 0 1 0 Object 4 1 0 0 1 0 1 Object 5 0 0 0 0 1 0 I have an idea to use an alternative, employing LinkedLists. My goal is to have an array of LinkedLists (one array entry for each object above, with the entry being the head pointers for each list) and the LinkedList for each object containing the labels of the other objects it is connected to. Here is my setup for the graph above.

Page 11: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

Here are a list of things I am worried about in working with my graph representation. Given what you know about arrays and LinkedLists and how I have used them above, for each question below, suggest whether or not the array approach or the LinkedList approach is likely to be a better choice and why. 6a) My graph does not have many links and memory usage is a concern. Since it says there are not many links, you should use a LinkedList, as it only requires representing the links that actually exist while the array holds information on all possible links. Each node in a LinkedList is actually twice as big as an array entry (8 bytes for a LinkedList node (4 for data, 4 for pointer) vs 4 bytes for the integer data in the array), so this argument breaks down once about half of the total possible links are present. 6b) I need to be able to quickly look into my representation and see if there is a link between any two arbitrary objects in the graph. Use the array, as it allows immediate access to spot [node1][node2]. This is a O(1) process. The LinkedList approach would require traversal down a list (maybe to the end of the list). This is O(n), where n is the number of objects in the graph in the worst case. 6c) I need to be able to quickly list all other objects in the graph who are linked to a given object in the graph. Use the LinkedList – traversal will give you all connected nodes for a given node. This is O(number of links for that node, which is <= number of objects in the graph). The array requires checking every spot in a row in the array to see if it holds a 0 or 1, which is O(number of objects in the graph).

Page 12: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

Problem 7. For each set of choices below, circle the choice you feel is most appropriate and briefly justify why. 7a) A container that will be used to store the UPC numbers of purchased items at a grocery store as they are scanned by a cashier. Choices:

Statically allocated array Dynamically Allocated Array LinkedList Justification: This container needs to grow at will – there is now way to know at the start of the day or at the start of checking out how many items will be swiped so this throws out the use of any type of array w/o wasting space or under allocating. The LinkedList is the only container we have seen which can grow to any size and grow at will. 7b) A sort that needs to run on a device with limited memory Choices: Insertion sort Merge sort Justification: This question is about how much memory is going to be used (bytes). Insertion sort requires 1 copy of the array and only makes entry on the function call stack. Merge sort requires 2 copies of the array (double the data), and it is recursive, meaning that it uses multiple function call stack entries.. 7c) A variable that is part of a class whose values should be able to be accessed/read, but not updated, by other parts of the program. Choices: Public Private Justification: Public allows anyone to read and to write, so it’s out. Private, but with a public accessor (getX()), will support reading but not writing/updating.

Page 13: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

Insertion Sort: void insertionSort(int* array, int size) { int k; int temp; int position; for (k = 1; k < size; k++) { temp = array[k]; position = k; while ((position > 0) && (array[position-1] > temp)) { array[position] = array[position-1]; position = position -1; } array[position] = temp; } }

Page 14: CSC 112 Final Exam Name: KEY - Wake Forest …csweb.cs.wfu.edu/~turketwh/CS112/Fall2009/exam/FinalExamKey.pdf · CSC 112 – Final Exam Name: KEY ... (assignment) - used in copying

Merge Sort: void merge(int* array, int* tempArray, int low, int middle, int high) { int i, j, k; for (i = low; i <= high; i++) { tempArray[i] = array[i]; } i = low; j = middle+1; k = low; while ((i <= middle) && (j <= high)) { if (tempArray[i] <= tempArray[j]) array[k++] = tempArray[i++]; else array[k++] = tempArray[j++]; } while (i <= middle) array[k++] = tempArray[i++]; } void mergeSortHelper(int* array, int* tempArray, int low, int high) { if (low < high) { int middle = (low + high) / 2; mergeSortHelper(array, tempArray, low, middle); mergeSortHelper(array, tempArray, middle+1, high); merge(array, tempArray, low, middle, high); } } void mergeSort(int* array, int size) { int* tempArray = new int[size]; mergeSortHelper(array, tempArray, 0, size-1); delete [] tempArray; }