This sample final contains the kinds of questions that will be on the actual final. It is much longer than the final will be. At least one question on the final will be all but identical to one here. The final is comprehensive: at least one question will come from the first half of the course. See the sample midterm for examples of such questions.
We will not post solutions to the sample final problems because, in our experience, people will be tempted to look at the solution before completely doing the problem. If anyone wishes to check their answers, they may give us a paper copy for review.
remove(),
and why is it even harder once we consider remove?
Explain by suggesting possible implementations.
remove since we didn't have
dummy nodes. Why do you think we don't use dummy nodes for the buckets?
remove() method of an iterator be called?
What element does it remove? Why have the restriction?
remove).
Give a reason for
this rule in the case of an array list (using a dynamically sized array, in
which an iterator has a pointer to the array) and in the case of
list (using linked list nodes, in which case the iterator points to
one or more list nodes).
@SuppressWarnings("unchecked") and
when not?
insertion sort algorithm.
Under what conditions does it do particularly well?
mergesort algorithm.
What algorithmic technique does it use?
When is this algorithm to be preferred over insertion sort?
addAttr in
AbstractShape which simply throws an exception?
What design pattern is it a part of? What role does it play?
Read the solutions to Homeworks 1-14 and answer the following questions:
move() never call paintContents?
What could happen wrong if we did so?
paintContents() never call move() ?
What could happen wrong if we did so?
setX method?
_data.length and
_manyItems ?
DiskSeq.append call ensureCapacity
every time it is called? Isn't that inefficient?
remove require a for-loop ?
parseString has an error?
Why not simply print an error message?
parseInt
throws an exception? Why don't we just fix our bug?
_done and _stopped
?
Can we be done when we're not stopped (still moving) ?
Can we be stopped if we're not done?
CarControlSeq, why does the iterator function
return this ?
(Why not make it a void method?)
_wellFormed count up the nodes rather than just
calling size() ?
precursor is null or
in the
list.
What would it mean to be non-null and not be in the list? How could that
happen?
appendAll has an empty for-loop in it. What's the point?
clone ?
cursor to be null? (See,
e.g. hasNext().)
Key interface?
Why does it not include any code?
removeFirst includes a condition in which along one
branch, two pointers are assigned and in the other only one pointer
is assigned. This is usually the sign of a bug. Why not in this
case? (What is the missing assignment?)
sortForward, we have the condition: if (p != t._prev)What does this condition refer to? What would be true if the two pointers were equal?
sortForward be very efficient even if started
at the front? (It has two nested while loops.)
cursor is a ``ghost field.'' What does that mean?
hasNext get its value? How does next() set its value?
appendAll special cases the empty addend.
Would the rest of the code work properly for this case?
Explain!
append have to be more complex, if we didn't have a dummy node?
clone() why is it necesary to change
answer.precursor ?
add, we have the line:_tail = _tail.next = new Node<T>(x,_tail.next);Why don't we simply say
_tail = new Node(...).
Would there be any difference?
clear() method.
LinkedList.this._wellFormed() in the iterator
code mean?
next() ensure you don't go around in cycles
forever?
MyIterator.remove there is the line:_myVersion = ++_version;What does this line do? (It does two things!) If this line were omitted, what problem would result? What if it simply said
++version ?
ensureCapacity need both i and j
when copying elements from one array to another?
offer rejecr null?
Would anything go bad if it accepted null?
poll shift all the remaining elements over?
clear allocate a new array?
if (++k >= _data.length) k = 0; _data[j] = _data[k];
k if it falls off the end, but not j. Why not?
What is the relation between j and k ?
_checkInRange have? Why something
so complicated?
add permit two listings to have the same
price? What would happen if a different listing (different
addresses) with the same price was added?
remove, there is a second while loop:
while (t.left != null) {
lag = t;
t = t.left;
}
What is this loop doing? Why?
addAll, the solution gives both efficient and
inefficient code. What is inefficient about the (much cleaner
looking) ``inefficient code'' ?
int n1 = add(array[mid]) ? 1 : 0;
_pending nodes represent?
hasNext there are three separate cases. Indicate what
state the system is in (in terms of the client) that these three
cases refer to.
next() has duplicated code (two similar or
even identical while loops).
Could the last two cases of next() be combined?
remove() marked
``overwrite'' ? Explain!
if (h > i) {
if (h <= lastNull || lastNull < i ) return _report(...)
} else {
if (h <= lastNull && lastNull < i) return _report(...)
}
Draw pictures to explain what these conditions mean.
rehash method may descrease the size of the
array. When does that happen?
++h; if (h == _contents.length) h = 0;What is going on? Why?
add, we have the following condition:
if (l2 == dummyListing) {
if (place == -1) place = h;
}
What is that code doing? Explain!
put sometimes increment _numListings,
sometimes _numUsed,
sometimes neither (returning early), but never _numUsed by
itself? What do these three cases
represent?
_ropen a different size than _copen?
read says it may throw an IOException but in the
code, it only throws ParseException. Why is this accepted by
the compiler.
If we changed IOException in the method header to
ParseException, the
code would not compile any more. Why not?
findPath know if it has reached the goal?
findPath ensures that the stack always
includes a path. How does it ever consider an alternate route from
a node?
Why? What would happen if we didn't do that?
if (_marked[_rows-1][0]) {
g.fillRect(0, (2*_rows-1)*SQUARESIZE, SQUARESIZE, 2*SQUARESIZE);
g.fillRect((2*_columns-1)*SQUARESIZE, 0,2*SQUARESIZE, SQUARESIZE);
}
What is this code doing? Why is there a condition?
Icon inherit from CenteredShape ?
Why not Polygon or Triangle ?
Trianglke inherit from Polygon when
Rectangle does not?
CenteredShape abstract whereas Polygon is not?
Disk not initialize the
radius attribute?
Point... mean?
Please answer the following questions about this code:
previous and
next ? Why do we return previous.data at the end of
next(), not the more reasonable next.data ?
next.right == null signify about
the iterator with respect to the tree rooted at ``next.''?
next.parent is null in the while loop of the first
branch, what does that mean?
private Set<Node> visited = new HashSet<Node>();
/**
* Initialize for a new search
*/
protected abstract void init();
/**
* Add a search state to be considered later
* @param s search state to add.
*/
protected abstract void add(SearchState s);
/**
* Are there any more search states to consider?
* @return whether there are any more search states
*/
protected abstract boolean hasNext();
/**
* Return next search state to consider
* @return
*/
protected abstract SearchState next();
public SearchState find(Node from, Node to) {
visited.clear();
init();
add(new SearchState(from));
while (hasNext()) {
SearchState s = next();
Node last = s.last();
if (last == to) {
return s;
} else if (!visited.contains(last)) {
visited.add(last);
for (Edge edge : last.edges()) {
add(s.extend(edge));
}
}
}
return null;
}
...
public class SearchState implements Iterable<Edge> {
private Node initial;
private List<Edge> path;
public SearchState(Node i) {
initial = i;
path = new ArrayList<Edge>();
}
public Node first() {
return initial;
}
public Iterator<Edge> iterator() {
return path.iterator();
}
/**
* Return the last node on this path.
* If the path is empty, we're still in the initial node.
* @return last node on path
*/
public Node last() {
...
}
/**
* Return a new search state which is like this one except
* with a path extended by the given edge.
* @param e edge to add to new state's path.
* @return new search state.
*/
public SearchState extend(Edge e) {
...
}
}
}
visited play? What would happen if we
moved the call to clear the visited set into the ``while'' loop?
add and next be implemented to achieve
depth-first search? breadth-first search? Why?
class TreeSet <T extends Comparable<T>> {
private static class Node<T> {
T data;
Node<T> left, right;
Node(T d) {data = d; }
}
private Node<T> root;
private void doPrint(Node n, int indent) { ... }
public void print() { doPrint(root,0); }
...
};
It is your task to implement doPrint, a helper method
for print.
This member function should print the tree where each element is
indented by two spaces more than the parent, and the data should be
printed in order.
For example, in the following picture, the tree on the left should be printed in the manner shown on the right:
|
1
3
5
6
8
9
|
ArrayList.
You should implement the five functions:
isEmpty, size, enqueue, front, and
dequeue.
Dictionary ADT with a single-linked list without
a dummy node.
NB: THIS QUESTION IS STILL IN C++
class Graph {
private:
unsigned int nodes;
vector<vector<int> > adjacent;
public:
Graph(unsigned);
unsigned get_nodes() const;
void add(int from, int to);
typedef vector<int>::const_iterator const_iterator;
const_iterator adj_begin(int) const;
const_iterator adj_end(int) const;
};
class Customer {
public Customer(String name) {...}
public void setAccount(Account a) {...}
public Account getAccount() {...}
}
class Account {
public Account(Money initial) {...}
public void setBalance(Money b) {...}
Money getBalance() {...}
}
For a new customer that does not yet have an account, both a customer
record and an account get dynamically allocated, with an initial
deposit of $100 (i.e., Money(100)). The customer record and the account must be added to their respective collections in the most convenient way.
Write the body of a function that creates a new customer and account (with 100 dollars) using the customer name passed as a string:
Collection<Customer> customers;
Collection<Account> accounts;
...
Customer createCustomerAndInitialAccount(string name)
{
// {Your code here!}
}
totalDeposits
function that computes the total amount of money in all the
accounts. Assume that Money has a method:void add(Money m);Make sure you don't modify any of the accounts!
Money totalDeposits()
{
Money total = new Money(0);
// Your code here!
// System.out.println("The total amount is " + total);
return total;
}
class Stack<T> {
T[] contents;
int used;
private T[] makeArray(int n) {
contents = (T[])new Object[n];
}
public Stack() { ... }
public boolean isEmpty() { ... }
public void push(T x) { ... }
public T pop() { ... }
};
MyEntry
NB: You should use both AbstractMap and AbstractSet.
(Why?)
/*
* Each node permits iteration to the djoining nodes.
*/
class Node implements Iterable<Node> {
public String getName();
...
};
/*
* Return whether a path can be found to the goal.
* Return null if no path can be found.
*/
List<Node> findPath(Node from, Node to, Set<Node> visited, List<Node> sofar) {
...
}
class HashTable<K,V> ... {
static class HashEntry<K,V> ... {
K key;
V value;
HashEntry<K,V> next;
};
HashEntry<K,V>[] contents;
int numEntries;
int hash(K key) { ... } // return value in range [0,contents.length)
}
You can assume the existence of boolean _report(String s).
You don't need to check that there are no duplicates.
class HashSet<K> ... {
K[] contents;
int numEntries;
K nullObject = (K) new Object(); // fill-in for null
K noObject = (K) new Object(); // place holder for removed entry
int hash(K key) { ... } // return value in range [0,contents.length)
}
NB: make sure you handle the result of probing.
You don't need to check that there are no duplicates.
Hint: you don't need to treat nullObject specially. (Why not?)
(NB: This question by itself is too hard for a final exam.)
class Shape {
// draw the shape on a canvas
public void draw(Canvas c) {}
// translate the shape by vector in d
public void move(Delta d) {
throw new UnsupportedOperationException("move not implemented");
}
}
class Line extends Shape {
private Point point1, point2;
public Line(Point p1, Point p2) {
point1 = p1;
point2 = p2;
}
// @Override
public void drawShape(Canvas c) { ... }
@Override
public void move(Delta d) { ...}
}
class Square extends Shape {
public Square(Point c, int s) { ...}
// @Override
public void drawShape(Canvas c) { ...}
public void move(int dx, int dy) { ...}
private Point center;
private int size;
}
...
List<Shape> shapes = new ArrayList<Shape>();
shapes.add(new Square(new Point(10,10),4));
shapes.add(new Line(new Point(0,0), new Point(30,30)));
Canvas canvas = new Canvas(40,40);
for (Shape s : shapes) {
sh.draw(canvas);
}
canvas.dump(System.out);
shapes.get(0).move(new Delta(5,0)); // move Square
Canvas works correctly.
How should the
Shape class be modified to avoid errors related to its' subclasses?
We have written the following code to implement cloning of a Set implemented with binary search trees (with parent pointers):
class Set<T> {
private static class Node<T> {
Node<T> parent;
T data;
Node<T> left,right;
Node(Node<T> p, T d) {
parent = p;
data = d;
}
}
private Comparator<T> comparator;
private Node<T> root;
private int numItems = 0;
...
@SuppressWarnings("unchecked")
public Set<T> clone()
{
Set<T> result;
try
{
result = (Set<T>) super.clone( );
}
catch (CloneNotSupportedException e)
{
// This exception should not occur. But if it does, it would probably
// indicate a programming error that made super.clone unavailable.
// The most common error would be forgetting the "Implements Cloneable"
// clause at the start of this class.
throw new RuntimeException
("This class does not implement Cloneable");
}
result.root = new Node<T>(null,root.data);
result.root.left = root.left;
result.root.right = root.right;
return result;
}
}
This code works fine when the set has exactly one element, but crashes
if it is empty, and strange things sometimes seem to handle if there is more
then one element. For instance the invariant might fail suddenly at
the start of a public method.
SortedList is just a sequence of values that
are kept sorted in ascending order.
Consider the following version of SortedList#locate for a linked list
implementation:
class SortedList<T> {
static class Node {
T data;
Node pNext;
};
Node pHead;
...
};
...
/** Return (0-based) position of item in sorted list.
* In other words, return number of items before this one in the list.
* Return -1 if the item isn't found.
* preconditions: none
*/
public int locate(T item)
{
Node p = pHead;
int count = 0;
while (p.pNext != null && p.pNext.data != item) {
p = p.pNext;
count++;
if (p.data == item) return count;
}
return -1;
}
The code does not work:
public int locate(T item)
{
Node p = pHead;
int count = 0;
while (p.pNext != null && p.data != item) {
p = p.Next;
++count;
}
return (p.pNext == 0) ? -1 : count;
}
If you call locate() on an empty SortedList, the program
dies with a null pointer exception.
If the item you're looking for is at the end of the list, the method
returns -1.
Otherwise, the correct value is returned. What is wrong? Fix the problem(s).
XMLEntity class includes the following methods:
public void addAttribute(String name, String value) { ... } // warn
public void addXMLEntity(XMLEntity value) { }
Someone implemented Item incorrectly:
private int worth;
public void addAttribute(String key, int value) {
println("Got here!");
if (key == "worth") {
worth = value;
}
super.addAttribute(key,"value");
}
But no matter what they put in the XML, it never printed
Got here.
super.addAttribute(key,value)
but Eclipse said that was an error. Putting quotes around
"value" worked. Why is this the wrong solution, in any case?
Got here never gets printed?
Unknown attribute: worthand all objects have zero worth when we sell them. What is the problem?
public class Person {
private int id;
private String firstName, lastName;
public Person() {}
public Person(int id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public String getFormattedName() {
return firstName + " " + lastName;
}
}
public class Student extends Person {
private double gpa;
public Student(int id, String firstName, String lastName, double gpa) {
this.gpa = gpa;
}
public double getGPA() {
return gpa;
}
}
public class Teacher extends Person {
private String title;
private boolean isTenured;
public Teacher(int id, String firstName, String lastName,
String title, boolean isTenured) {
this.title = title;
this.isTenured = isTenured;
}
public boolean getIsTenured() {
return isTenured;
}
@Override
public String getFormattedName() {
return title + " " + firstName + " " + lastName; // error #1
}
}
We use the following driver:
public class Main {
public static void main(String[] args) {
Teacher a = new Teacher(100, "Mary", "Jo", "Dr.", true);
Person b = new Student(200, "John", "Doe", 3.8);
printPersonInfo(a);
printPersonInfo(b);
}
public static void printPersonInfo(Person p) {
System.out.println(p.getFormattedName());
if(p instanceof Student) {
System.out.println("GPA: " + p.getGPA()); // error #2
} else if(p instanceof Teacher) {
System.out.println("Tenured: " + p.getIsTenured()); // error #3
}
}
}
firstName and lastName are not visible.
getGPA is undefined for the type Person.
getIsTenured is undefined for the type Person.
Explain each of these error messages.
Dr. null null Tenured: true null null GPA: 3.8Why? Please explain!