CS61BL Summer 2013 Midterm 2

Similar documents
CS 61B (Clancy, Yelick) Solutions and grading standards for exam 2 Spring 2001 Exam information

Note that if both p1 and p2 are null, equals returns true.

Account joeacct = new Account (100, new Account (500)); Account joeacct = new Account (100, new Account (500, null));

EXAMINATIONS 2015 COMP103 INTRODUCTION TO DATA STRUCTURES AND ALGORITHMS

CS61BL: Data Structures & Programming Methodology Summer 2014

Summer Final Exam Review Session August 5, 2009

CMSC131. Inheritance. Object. When we talked about Object, I mentioned that all Java classes are "built" on top of that.

EXAMINATIONS 2016 TRIMESTER 2

Topic 10: The Java Collections Framework (and Iterators)

Separate Compilation and Namespaces Week Fall. Computer Programming for Engineers

CSE373 Fall 2013, Second Midterm Examination November 15, 2013

Java Review: Objects

CSE 143 Sp03 Final Exam Sample Solution Page 1 of 13

CS 61B Midterm 2 Guerrilla Section Spring 2018 March 17, 2018

CS11 Java. Winter Lecture 8

COMP 103 Introduction to Data Structures and Algorithms

CS 61B, Spring 1999 MT3 Professor M. Clancy

Stacks and Queues. David Greenstein Monta Vista

Prelim 1 SOLUTION. CS 2110, September 29, 2016, 7:30 PM Total Question Name Loop invariants. Recursion OO Short answer

CS 3L (Clancy) Solutions and grading standards for exam 1

Lesson 10A OOP Fundamentals. By John B. Owen All rights reserved 2011, revised 2014

CS 251 Intermediate Programming Inheritance

CS211 Computers and Programming Matthew Harris and Alexa Sharp July 9, Boggle

CS 61B, Midterm #3 and solutions, Spring 1996

CS61BL: Data Structures & Programming Methodology Summer Midterm 1 Solutions. public static boolean probablyequals( Object obj1, Object obj2 ) {

Section 05: Solutions

Data Structures and Algorithms Notes

CS61BL. Lecture 3: Asymptotic Analysis Trees & Tree Traversals Stacks and Queues Binary Search Trees (and other trees)

Computer Science E-119 Fall Problem Set 4. Due prior to lecture on Wednesday, November 28

CS314 Exam 2 - Spring Suggested Solution and Criteria 1

CS 61BL Data Structures & Programming Methodology

182 review 1. Course Goals

+ Abstract Data Types

CSE 143 Au03 Final Exam Page 1 of 15

Lab 4: Super Sudoku Solver CSCI 2101 Fall 2017

CS 61B Spring 2017 Guerrilla Section 3 Solutions

EXAMINATIONS 2005 END-YEAR. COMP 103 Introduction to Data Structures and Algorithms

CS313D: ADVANCED PROGRAMMING LANGUAGE

CSC 1351: Final. The code compiles, but when it runs it throws a ArrayIndexOutOfBoundsException

COMP 250 Midterm #2 March 11 th 2013

EXAMINATIONS 2012 MID YEAR. COMP103 Introduction to Data Structures and Algorithms SOLUTIONS

Recap. List Types. List Functionality. ListIterator. Adapter Design Pattern. Department of Computer Science 1

About this exam review

CPSC 221: Algorithms and Data Structures Lecture #1: Stacks and Queues

Fall 2017 Mentoring 9: October 23, Min-Heapify This. Level order, bubbling up. Level order, bubbling down. Reverse level order, bubbling up

Points off Total off Net Score. CS 314 Final Exam Spring Your Name Your UTEID

(f) Given what we know about linked lists and arrays, when would we choose to use one data structure over the other?

FINAL EXAMINATION. COMP-250: Introduction to Computer Science - Fall 2011

CS 61B Spring 2017 Guerrilla Section 3 Worksheet. 25 February 2017

Building Java Programs

CPSC 221: Algorithms and Data Structures ADTs, Stacks, and Queues

Building Java Programs

CS106X Final Review. Rachel Gardner and Jared Bitz. slides adapted from Ashley Taylor, Anton Apostolatos, Nolan Handali, and Zachary Birnholz

Inheritance. Transitivity

Model Solutions. COMP 103: Test May, 2013

Review. CSE 143 Java. A Magical Strategy. Hash Function Example. Want to implement Sets of objects Want fast contains( ), add( )

FINAL EXAMINATION. COMP-250: Introduction to Computer Science - Fall 2011

Solutions and grading standards

AP Computer Science 4325

Points off Total off Net Score. CS 314 Final Exam Spring 2017

11 HashMap: Overriding equals ; JUnit; Vistors

CS61B Spring 2016 Guerrilla Section 2 Worksheet

Chief Reader Report on Student Responses:

AP Computer Science AB 2005 Scoring Guidelines

CS313D: ADVANCED PROGRAMMING LANGUAGE

SOLUTIONS. COMP103 Introduction to Data Structures and Algorithms

Interview Questions I received in 2017 and 2018

8*4 + 4 = 36 each int is 4 bytes

Hash tables. hashing -- idea collision resolution. hash function Java hashcode() for HashMap and HashSet big-o time bounds applications

Faculty of Science FINAL EXAMINATION COMP-250 A Introduction to Computer Science School of Computer Science, McGill University

Total Score /15 /20 /30 /10 /5 /20 Grader

1.00/1.001 Introduction to Computers and Engineering Problem Solving. Final Exam

CS61B (Clancy) Spring 1996 Exam 3, solutions, and grading standards. April 12, 1996 Exam 3

University of Waterloo Department of Electrical and Computer Engineering ECE 250 Algorithms and Data Structures

Points off Total off Net Score. CS 314 Final Exam Spring 2016

CS314 Exam 1 - Fall Suggested Solution and Criteria 1

Abstract vs concrete data structures HEAPS AND PRIORITY QUEUES. Abstract vs concrete data structures. Concrete Data Types. Concrete data structures

Computer Science 62. Bruce/Mawhorter Fall 16. Midterm Examination. October 5, Question Points Score TOTAL 52 SOLUTIONS. Your name (Please print)

EXAMINATIONS 2006 SUMMER TRIMESTER. COMP103 Introduction to Data Structures and Algorithms

Student Performance Q&A:

Collections, Maps and Generics

Data Structures. COMS W1007 Introduction to Computer Science. Christopher Conway 1 July 2003

Computer Science 210 Data Structures Siena College Fall Topic Notes: Linear Structures

1 Inheritance (8 minutes, 9 points)

CIS 120 Midterm II November 16, 2012 SOLUTIONS

CMPSCI 187: Programming With Data Structures. Review for Final Exam David Mix Barrington 10 December 2012

CS18000: Problem Solving And Object-Oriented Programming

The class Object. Lecture CS1122 Summer 2008

Tutorial #11 SFWR ENG / COMP SCI 2S03. Interfaces and Java Collections. Week of November 17, 2014

Part I: Short Answer (12 questions, 65 points total)

CS 314 Final Fall 2011

CS 314 Midterm 2 Fall 2012

USAL1J: Java Collections. S. Rosmorduc

Today. Book-keeping. Exceptions. Subscribe to sipb-iap-java-students. Collections. Play with problem set 1

CS 61BL Midterm 2 Review Session. Chris Gioia, Patrick Lutz, Ralph Arroyo, Sarah Kim

Programmieren II. Polymorphism. Alexander Fraser. June 4, (Based on material from T. Bögel)

Midterm Exam 2 CS 455, Spring 2011

Keeping Order:! Stacks, Queues, & Deques. Travis W. Peters Dartmouth College - CS 10

Midterm Exam 2 CS 455, Spring 2015

1) Holiday Lights 30 Points

Transcription:

CS61BL Summer 2013 Midterm 2 Sample Solutions + Common Mistakes Question 0: Each of the following cost you.5 on this problem: you earned some credit on a problem and did not put your five digit on the page, you did not adequately identify your lab section, or you failed to put the names of your neighbors on the exam. The reason for this apparent harshness is that exams can get misplaced or come unstapled, and we want to make sure that every page is identifiable. We also need to know where you will expect to get your exam returned. Finally, we occasionally need to verify where students were sitting in the classroom while the exam was being administered.

Question 1A: Sample Solution (Version A): public class TrackedQueue extends Queue { private int mymaxsize; // technically, this constructor is unnecessary // but you didn t lose points if you implemented it correctly public TrackedQueue() { super(); mymaxsize = 0; public void enqueue(object obj) { super.enqueue(obj); if (size() > mymaxsize) { mymaxsize = size(); public int maxsizesofar() { return mymaxsize; There were two main issues that students frequently encountered. The first was not realizing that inheritance would do most of the work for you. That is, since you extend from the Stack class, you don t need to define a peek(), pop(), or size() method the only thing you need to override is the push() method. For the other test version, you extend from a Queue, which means you do not need to override the peek(), dequeue() or size() methods, only the enqueue() method. The other main mistake was not realizing that you have to compare mymaxsize (or whatever int variable you made) to super.size() in the push() method. You only want to increment mymaxsize if ( mymaxsize<super.size() ), because otherwise you are keeping track of the total number of calls to push/enqueue, instead of the largest count that we ve seen so far. This distinction caused a number of students to lose points.

Question 1B: Sample Solution (Version A): (For version B replace Queue with Stack and enqueue with push ) Queue myq = new TrackedQueue(); System.out.println(myQ.maxSizeSoFar()); // Compile time error: can t find maxsizesofar in Queue TrackedQueue myq = new Queue(); System.out.println(myQ.maxSizeSoFar()); // Compile time error: static type is a subclass of the dynamic type Queue myq = new TrackedQueue(); myq.enqueue( MIKE ); // Both TrackedQueue.enqueue() and Queue.enqueue() are called For the first part, the most common mistake was getting it completely wrong by saying that there s no error. The error is in the second line remember that Java checks the static class during compile time, and the dynamic class during run time. Since myq is of static type Queue and Queues don t have maxsizesofar(), there s a compile time error. For the second part, the most common mistake was being confused about run time error vs compile time error. Or rather, they detected the run time error in the second line if the first line was allowed to compile. However, the first line doesn t compile because saying that a Queue is a TrackedQueue is false not all Queues are TrackedQueues. Java will complain about incompatible types. In the third part, most people didn t realize that both TrackedQueue s enqueue() and Queue s enqueue() are called. First, TrackedQueue s enqueue() method is called, which, if you implemented 1a correctly makes a call to super.enqueue().

Question 2: Sample Solution (Version A): A, Enqueue: linear time; need to free up a slot by shifting all elements by 1 slot. A, Dequeue: constant time; simply call ArrayList.remove(N 1). Sample Solution (Version B): A, Enqueue: constant time; simply call ArrayList.add() at the back of the queue A, Dequeue: linear time; remove the first element, then shift all other elements by 1 slot. Sample Solution (Both Versions): B, Enqueue: constant time; adding to the front of a linked list takes constant time B, Dequeue: linear time; need to traverse the entire list to access the next to last node The most common mistake was B, dequeue not realizing that since you don t have previous pointers, you can t access the next to last node without traversing the entire list in linear time. Another common mistake was not realizing that removing or adding something to the beginning of an arraylist (at index 0) requires a shift of all the items in the ArrayList, which is linear. However, adding to the end or removing the end of an ArrayList is in constant time because you can access ArrayLists by index (ArrayList is implemented as an Object array). To access the last item we can do something along the lines of arraylist.get(size() 1). It is NOT necessary to traverse the whole arraylist to find the last index. The last common mistake was not reading the implementations correctly, particularly for B enqueue... Many people were trying to enqueue the new node to the back of the list even though according to the implementation the back of the queue is the front of the list (so you want to add to the front of the list).

Question 3A: (3B on Exam B) Sample Solution: Changing the hashcode() function causes every value to have the same hash code (10). This means they all hash to the same bucket, and a very large chain will form. This will cause adding new keys, or looking up values, to be very slow, as we now need to essentially look through a LinkedList. This loses any benefits the HashMap would ve given us. Most points lost here were for not being specific in answers. For example, stating that there would be many collisions (or many items in the same bucket), but not explaining that it causes the HashMap to act like a LinkedList or run very slowly. Question 3B: (3A on Exam B) Sample Solution: When a key is added to the HashMap, HashMap first computes the hashcode of the key to determine its bucket. Then, within that bucket, it uses.equals() to determine if the new key is already in the HashMap... and overwrites it if there is. This means in each bucket, there will be at most one key/value pair. contains() and get() will also act oddly, returning true (or a value) so long as there s something in the correct bucket, regardless of whether or not the keys are equal. To get full credit, you must have explicitly mentioned the erroneous behavior of adding two different keys that hashed to the same bucket, even if you correctly identified the behavior of contains() and/or get(). The most common mistake was assuming that objects were added to the HashMap normally, and that calls to get() would return the first value from the appropriate bucket. This has the same effect as overwriting the keys, but technically is not what s happening behind the scenes. Another common mistake was assuming that hashcode() had changed. In most cases, there is an invariant which says your HashMap will not function correctly unless equal objects have the same hash code. In this case, we were not working with hashcode(), all we did was change equals(). Changing one does not automatically affect the other. A less common mistake was assuming that only one object could be stored in the HashMap at a time. This is incorrect, as each bucket can have a key/value pair. This misconception either stems from assuming we changed hashcode(), or assuming HashMap checks ALL buckets for equal keys before adding new values.

Question 4A (Both Versions): /* Sample Solution 1 */ public void isok() throws IllegalStateException { Iterator<Amoeba> iter = allamoebas(); HashSet<String> names = new HashSet<String>(); while (iter.hasnext()) { Amoeba a = iter.next(); if (names.contains(a.myname)) { throw new IllegalStateException ("duplicate name = " + a.myname); names.add(a.myname); // or if (!names.add(a.myname)) { throw... /* Sample Solution 2 */ HashSet<String> allnames = new HashSet<String> ( ); public void isok ( ) throws IllegalStateException { helper (myroot); private void helper (Amoeba current) { if (current == null) { return; if (allnames.contains (current.myname)) { throw new IllegalStateException ("duplicate name: " + current.myname); allnames.add (current.myname); Iterator<Amoeba> iter = current.mychildren.iterator ( ); while (iter.hasnext ( )) { helper (iter.next ( ));

/* Sample Solution 3 */ /* Note: This solution would earn only 2.5 out of 5, since it runs in time proportional to N squared. */ public void isok ( ) { AmoebaIterator iter1 = allamoebas ( ); while (iter1.hasnext ( )) { Amoeba a1 = iter1.next ( ); AmoebaIterator iter2 = allamoebas ( ); while (iter2.hasnext ( )) { Amoeba a2 = iter2.next ( ); if (a1!= a2) { if (a1.myname.equals (a2.myname)) { throw new IllegalStateException ("duplicate name :" + a1.myname); One of the most common errors was attempting to hash Amoeba objects, which doesn t work since we have not overridden Amoeba s hashcode. Instead, you should hash their names directly, because String does have an overridden hashcode. Some students still had troubles instantiating an iterator or differentiating between the AmoebaFamily and AmoebaClasses. The method you have to write is in AmoebaFamily, and so you can call the method allamoebas() which returns an iterator over all Amoebas in the tree, which greatly simplifies the problem. You can also just construct a new AmoebaIterator() since AmoebaIterator is a public class inside AmoebaFamily. You cannot create an iterator over all Amoebas in the tree from a single Amoeba; however, you can create an iterator only over its immediate children by taking advantage of ArrayList s iterator, which is what you needed to do if you attempted a recursive solution. For students that tried recursion instead of iteration, a common mistake was to not pass your HashSet of seen names through calls. If you don t pass it in then you won t be able to check against the names you ve seen in other calls. An alternative solution to this problem is to make the HashSet an instance variable of AmoebaFamily, so all your recursive calls can access it (provided the recursive calls are not static). The heaviest deductions were for slow solutions (using an ArrayList instead of a HashSet, or doing nested iterations and not saving the names at all). These slow solutions run in O(n^2) time rather than O(n), which was unacceptable.

Some students also didn t realize that the instructions to use a hash table meant they could use a HashSet or a HashMap. hash table is just a generic term that can refer to either. HashSet suited this problem better, but some students made a HashMap work and weren t deducted for it. Question 4B: Version A: Correct Answer: Wilma, Hilary, Homer Partial Credit (Reversed Depth First, or pushed in wrong order): Homer, Hilary, Wilma Version B: Correct Answer: Marge, Bart, you Partial Credit (Reversed Depth First, or pushed in wrong order): You, Bart, Marge Some answers saw that we were using a stack, and assuming the order based on that... Amoebas were pushed onto the stack left to right, which causes the traversal to go down the right side of the tree first. Some students confused breadth first with other traversals, or had no clear pattern to how they traversed the tree. Putting down the same Amoeba multiple times (or naming an Amoeba we did not ask for) were considered completely wrong.

Question 5: /* Sample solution */ public boolean samecomputation (BinaryTree expr) { return helper (myroot, expr.myroot); private boolean helper(treenode root1, TreeNode root2) { if (root1 == null) { return root2 == null; if (root1.myoper == root2.myoper) { if (root1.myoper == + ) root1.myoper == * ) { return (helper (root1.myleft, root2.myleft) && helper (root1.myright, root2.myright) (helper (root1.myleft, root2.myright) && helper(root1.myright, root2.myleft)); else { // else not necessary return (helper (root1.myleft, root2.myleft) && helper (root1.myright, root2.myright)); else { return false; One common mistake was to avoid using helper methods. Unless you knew how to compare the trees iteratively using stacks, it simplified the problem to go straight into using a helper (with two TreeNode parameters) to solve it recursively. There were also many occurrences of confusion between TreeNodes and BinaryTrees (earning a deduction of at least 2). In terms of the recursive solution, a common mistake was to not carefully think about what base cases were needed. Based on how students carved out their answers, not all the base cases were the same for all solutions. Solutions flagged as bad base cases in the rubric included missing base cases along with comparing TreeNode references (e.g. myroot) rather than variables and operators (e.g. myitem). A few students didn t properly handle the cases for + and * carefully, which would result in all cases being meshed together. And surprisingly many solutions failed to combine the results of the recursive calls, for instance, as follows: helper (root1.myleft, root2.myleft); helper (root1.myright, root2.myright);

Question 6: Sample Solution (version A): p.myrest = sofar; sofar = p; p = temp; Sample Solution (version B): sofar = p; p = p.myrest; // or p = sofar.myrest; sofar.myrest = temp; The provided for loop hinted that students should have used iteration instead of recursion (let n be the number of nodes in the List; a recursive call to reversehelper would have resulted in anywhere from n 2 to n 3 to infinity calls to reversehelper). Students who used recursion or created additional ListNode objects received no credit. Some students also attempted to change nodes myfirst values and/or assign a ListNode to another node s myfirst, which resulted in incorrect solutions.