1.00/1.001 Introduction to Computers and Engineering Problem Solving Final Examination - December 15, 2003 Name: E-mail Address: TA: Section: You have 3 hours to complete this exam. For coding questions, you do not need to include comments, and you should assume that all necessary files have already been imported. Good luck! Question Points Question 1 / 10 Question 2 / 10 Question 3 / 20 Question 4 / 60 Total / 100 1 / 15 Question 1. True or False (10 points) Answer the following questions about Java by circling TRUE or FALSE as appropriate. 1) If a and b are two references of the same type, then a.equals(b) will return true if and only if a and b refer to the same object. TRUE FALSE 2) Collisions will never occur in a hash table that uses chaining. TRUE FALSE 3) Java streams are Last In, First Out stacks. TRUE FALSE 4) It is not possible to read and write one file using the same stream. TRUE FALSE 5) An inorder traversal will visit the nodes in a binary search tree in increasing order. TRUE FALSE 2 / 15 Question 2. Conceptual Question (10 points) There are situations or specific sets of data that can make an efficient algorithm or data structure give atypically inefficient or incorrect performance. Please describe at least two examples and strategies to remedy the problem in both cases. Example 1: A standard binary search tree will degenerate into a linked list if a sorted set of keys is inserted in order. This means that the tree’s normal insertion and retrieval time of O(log n) will worsen to that of a linked list, O(n). The solution us ed by most tree data structures in production algorithms is to rebalance the tree after certain operations if it starts to become unbalanced. Example 2: If simple quicksort uses the first or last element of the current array as the pivot and the sort is run on already sorted data, then one of the resulting subarrays will always contain only one element, and the efficiency of the sort will decrease from O(n lg n ) to O( n^2 ). Perversely, insertion sort, which usually runs in O( n^2 ), will run in O( n ) on presorted data, so insertion sort will actually run faster than quicksort in this case. The best approach to solving the problem is to choose the pivot more carefully. If the pivot is chosen as the median value of the first, last, and middle value of the array to be sorted, quicksort will maintain its O( n log n ) performance on all normal data. Example 3: If a hash map inserts keys which turn out to hash to the same slot or small set of slots, the performance on insertions and retrievals can decrease to O( n ) like a linked list rather than the normal O( 1 ). The solution is to use a better hash code method in the key class or if there is some periodicity in the key’s hash code that matches the number of cells in the hash map, to use a more sophisticated mapping of hash codes than taking the modulus. Making the hash function rehash the integer hash codes may help. 3 / 15 Question 3. Word Counting (20 points) Ever hungry in your quest to learn more about Java, you spend some time using Google to track down an electronic version of the seminal Java text: The Java Programming Language, Third Edition by Arnold, Gosling, and Holmes. As you settle down for a restful IAP, you notice that the word "java" appears 37 times on the first two pages of this book. This large number of occurrences leads you to wonder how many times "java" appears throughout the entire book. Thankfully, when you have the electronic format, you can write a program to parse the book and count up all of the occurrences. Remembering your Stream lectures, you are quickly able to write a piece of the program that reads in all of the words as Strings and stores them in a String[]. You decide that your next course of action will be to build a Map that maps the words to the number of times they occur.1 Specifically, you will map Strings to Integers. In the box below, write code that will create a Map and fill it so that the keys of the Map are the words in the book and the values are the number of times each word appears. The only variable you know about is the String[] words. This String array contains all of the words as they appear in they book but with each String changed to lowercase. For example, the first four words seen in the book are the title: "The Java Programming Language" so, words[0] = "the" words[1] = "java" words[2] = "programming" words[3] = "language" Realistically, you'd probably build the Map as you read in the electronic format of the book, s kipping the process of building the intermediate array of Strings. This change is made for the sake of simplicity. 4 / 15 Part 1 public class WordCount { public static void main( String [] args ) { String[] words; // will contain each word of book as a // separate element words = readWordsFromBook(); // The details of readWordsFromBook() are omitted. // You can safely assume that the array words is filled // with all of the words in the book. // This means that words.length is equal to the total // number of words in the book. // Your job is to write code to create and fill // the Map below: HashMap wordMap = new HashMap(); for(int i = 0; i < words.length; i++) { Integer count = (Integer) wordMap.get(words[i]); if ( count == null ) { wordMap.put(words[i], new Integer(1)); } else { wordMap.put(words[i], new Integer(count.intValue()+1); } } 5 / 15 Now that you've built a Map as described above, write code in the box below to print out the number of times that the word "java" occurred. Just for kicks, also print out the number of times that "MIT" occurred. Remember that the words[] array changes all text words to lower case. For both of these words, you should either print out that the word occurred 0 times or that it occurred N times, where N is positive. If you weren't able to complete the code in Part 1, assume that a Map, named wordMap, exists and contains the appropriate contents. If you were able to complete the code above, use the name of the Map that you created. Part 2 // continuing in the main() method from before Integer javaCount = wordMap.get("java"); if ( javaCount == null ) { System.out.println("java occurred 0 times."); } else { System.out.println("java occurred "+javaCount+ " times); } Integer mitCount = wordMap.get("mit"); if ( mitCount == null ) { System.out.println("mit occurred 0 times."); } else { System.out.println("mit occurred "+mitCount+ " times); } 6 / 15 Question 4. Swing Application for Stack (points) In this question, you will complete 2 java classes, MyStackModel and MyStackView in order to develop a graphical user interface for a Stack data structure. MyStackModel uses an instance of the SLinkedList from the lecture (#26) on singly linked lists to implement the stack. If you prefer, you can use the LinkedList class from the java.util package. Follow the directions in the next two parts to complete the java classes and be sure to take a careful look at the given methods before completing each part. Part 1. MyStackModel.java (points) In this part, you will complete the MyStackModel class, which uses an instance of SLinkedList to implement a Stack data structure. If you prefer, you may use the LinkedList class from the java.util package. If you choose to do this, you will have to change the code below. For each change you make, circle the old code that you are replacing and write your new code nearby. You may assume that all appropriate import statements have been made. The MyStackModel class will add or remove objects at the beginning of the linked list, elements, to implement the stack. MyStackModel.java: public class MyStackModel { private SLinkedList elements; public MyStackModel() { elements = new SLinkedList(); } // Remove all the elements public void clear() { elements.clear(); } // Push object into Stack public void push(Object obj) { // Problem 1 } // Pop object out of Stack public Object pop() throws EmptyStackException { // Problem 2 } 7 / 15 // Get all the elements in Stack public Object[] getAllElements() { // Problem 3 } } 1) Problem 1 Complete the push() method, which takes an Object as an argument and adds it to the Stack public void push(Object obj) { elements.addFirst(obj); } 2) Problem 2 Complete the pop() method, which pops the object that was last added to your Stack. You need to check first whether your Stack is empty or not. If your Stack is empty, throw an EmptyStackException (note the method signature). Otherwise, remove the object from the Stack and return it. public Object pop() throws EmptyStackException { if (elements.size() == 0) { throw new EmptyStackException(); } return elements.removeFirst(); } 8 / 15 3) Problem 3 Complete the getAllElements() method, which returns all the elements on the stack in an appropriately sized array. public Object[] getAllElements() { Object[] temp = new Object[elements.size()]; int i = 0; ListIterator iter = elements.listIterator(); while (iter.hasNext()) { temp[i++] = iter.next(); } return temp; } Part 2. MyStackView.java (points) In this part, you will complete the MyStackView class. When it is complete, your application will look like this initially: 9 / 15 When user clicks the ‘Push’ button, your program will get the text from JTextField (provided that user has put some text in JTextField) and push it onto your Stack (In this problem, all the objects in your Stack are Strings.) Also, the JTextArea will display all the elements in your Stack with the latest element on top. The setText() method of JTextArea takes a String as an argument and sets the text for JTextArea. Take a look at the clearButton.addActionListener() in the code on the bottom of p.12 to understand how the setText() method works. After adding one element, your application will look like this: After adding second and third elements, your application will look like this: 10 / 15 Hint: The String "\n" can be appended to a String to start a new line. When the user presses the “Pop” button, the program should pop the topmost String off the stack and throw it away. Please remember that the pop() method in MyStackModel class throws an EmptyStackException. Therefore, when you try to pop an element from an empty Stack, your application should generate an error message in a message dialog box: Here is the code for the MyStackView class. Please make sure you understand how all the graphical components are implemented. 11 / 15 MyStackView.java: import import import import java.awt.*; java.awt.event.*; java.util.*; javax.swing.*; public class MyStackView extends JFrame { private private private private private MyStackModel stack; JPanel controlPanel, stackPanel; JButton pushButton, popButton, clearButton; JTextField inputField; JTextArea stackArea; public StackGUI() { stack = new MyStackModel(); controlPanel = new JPanel(); stackPanel = new JPanel(); pushButton = new JButton("Push"); popButton = new JButton("Pop"); clearButton = new JButton("Clear"); inputField = new JTextField(20); stackArea = new JTextArea(20, 38); controlPanel.add(inputField); controlPanel.add(pushButton); controlPanel.add(popButton); controlPanel.add(clearButton); stackPanel.add(stackArea); getContentPane().add(controlPanel, "North"); getContentPane().add(stackPanel, "Center"); pack(); 12 / 15 // Add action listener for ‘Clear’ button clearButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { stack.clear(); stackArea.setText(updateList()); } }); // Add action listener for ‘Push’ button pushButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // Problem 1 } }); // Add action listener for ‘Pop’ button popButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // Problem 2 } }); } public String updateList() { // Problem 3 } } 1) Problem 1 Complete the actionPerformed method that will be called by the ‘Push’ button. First, get the text from JTextField and push it onto the Stack. Then, update the JTextArea using the updateList() method. (Hint: Take a look at the actionPerformed method for the ‘Clear’ button) pushButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { stack.push(inputField.getText()); stackArea.setText(updateList()); }}); 13 / 15 2) Problem 2 Complete the actionPerformed method for the ‘Pop’ button. Please remember that the pop() method in MyStackModel class throws an EmptyStackException. Therefore, use a try/catch block to make sure your ‘Pop’ button catches the exceptions thrown by the MyStackModel class. When an exception is caught, generate a pop-up error message by using showMessageDialog() method of JOptionPane (Refer to the figures on previous pages). Also, update the JTextArea using the updateList() method. popButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { Object obj = stack.pop(); stackArea.setText(updateList()); } catch (EmptyStackException ex) { JOptionPane.showMessageDialog(null, "Error: Stack is Empty. Nothing to Pop."); } } }); 14 / 15 3) Problem 3 Complete the updateList() method. This method gets all the elements from MyStackModel and creates a String that lists all the String objects in Stack. Make sure that JTextArea displays one String in each line (Refer to the figures on previous pages). public String updateList() { Object[] temp = stack.getAllElements(); String s = ""; for (int i = 0; i < temp.length; i++) { s += (String)temp[i] + "\n"; } return s; } 15 / 15