Problem #3
Solution:
public boolean equals(IntTree other) {
return equals(overallRoot, other.overallRoot);
}
private boolean equals(IntTreeNode root1, IntTreeNode root2) {
if (root1 == null || root2 == null)
return root1 == null && root2 == null;
else
return root1.data == root2.data
&& equals(root1.left, root2.left)
&& equals(root1.right, root2.right);
}
1 correct public header
1 private header with two tree nodes, call on private, public returns call on
private
3 base case when one of the roots is null
1 attempt (testing each root against null)
1 returns true when both are null (requires test)
1 returns false when only one is null (requires test)
5 recursive case
1 attempt to compare root1.data and root2.data
1 correctly returns false when root1.data != root2.data
1 recursive calls attempt (must see calls on equals(root1.left, root2.left)
and equals(root1.right, root2.right))
2 correct in all cases
Problem #4
Solution:
public class CachedSongList extends SongList {
private List songs;
private Map mp3s;
public CachedSongList(UserData data) {
super(data);
songs = new LinkedList();
mp3s = new HashMap();
}
public MP3 get(String name) {
if (mp3s.containsKey(name)) {
songs.remove(name);
songs.add(0, name);
return mp3s.get(name);
} else {
MP3 response = super.get(name);
songs.add(0, name);
if (songs.size() == 11) {
mp3s.remove(songs.get(10));
songs.remove(10);
}
mp3s.put(name, response);
return response;
}
}
public String getRecent(int index) {
return songs.get(index);
}
public int recentSize() {
if (songs.size() != mp3s.size())
throw new IllegalStateException();
return songs.size();
}
}
1 class header
4 fields
2 List for song names (-1 if not interface type)
2 Map or parallel List (-1 if not interface type)
-1 if nonprivate
3 constructor
1 header and super(data)
2 initialize their fields
1 attempt
1 correct
9 get
3 song already in the list
1 correct test for this case
1 moves this song to the top of the recent list
1 correctly returns cached MP3
6 song not in the list
1 correct call on super.get, stores result in a variable
1 adds this song/MP3 to the cache
1 puts this song at the top of the recent list/correctly shifts
1 removes the 11th song from list (if there is one)
1 removes the 11th MP3 from the cache (if there is one)
1 returns stored result
3 getRecent & recentSize
1 getRecent attempt
1 recentSize attempt
1 both correct
Array based solutions go to the question leader.
If they destroy a method they inherited (e.g., put, contains): -1, -2, -3 based
on quality (max -5).
Problem #5
Solution:
public class ItemOrder implements Comparable {
private String item;
private int quantity;
private int pricePer;
private String note;
public ItemOrder(String item, int quantity, int pricePer) {
this(item, null, quantity, pricePer);
}
public ItemOrder(String item, String note, int quantity,
int pricePer) {
this.item = item;
this.note = note;
this.quantity = quantity;
this.pricePer = pricePer;
}
public String getItem() {
return item;
}
public int getPrice() {
return quantity * pricePer;
}
public String toString() {
String text = "item #" + item;
if (note != null)
text += " (" + note + ")";
text = text + ": " + quantity + "@" + moneyString(pricePer) +
" = " + moneyString(getPrice());
return text;
}
private String moneyString(int cents) {
return "$" + cents / 100 + "." + cents % 100 / 10 + cents % 10;
}
public int compareTo(ItemOrder other) {
if (!item.equals(other.item))
return item.compareTo(other.item);
else
return other.getPrice() - getPrice();
}
}
1 class header
4 fields (1 point each, -1 if not private, okay to have a 5th field for
hasOptionalText)
3 two constructors
1 reasonable attempt for 3-argument constructor
1 reasonable attempt for 4-argument constructor
1 both correct (assign fields, etc)
1 getItem correct (does NOT include optional text)
2 getPrice
1 attempt
1 correct (not pricePer, but total price)
5 toString
1 properly converts pricePer to dollars/cents ignoring 0 after decimal
1 properly converts total price to dollars/cents ignoring 0 after decimal
1 properly handles 0 after decimal in two previous
1 string also includes item and quantity fields
1 otherwise correct (-1 if System.out)
4 compareTo
1 attempt to compare the item numbers (some kind of test, attempt to call
compareTo on the strings)
1 attempt to compare the prices (could be comparing pricePer, return
some kind of difference)
1 correct order (item numbers first, then price)
1 otherwise correct
Problem #6
Solution:
public IntTree combineWith(IntTree other) {
IntTree result = new IntTree();
result.overallRoot = combine(overallRoot, other.overallRoot);
return result;
}
private IntTreeNode combine(IntTreeNode root1, IntTreeNode root2) {
if (root1 == null)
if (root2 == null)
return null;
else // root2 != null
return new IntTreeNode(2, combine(null, root2.left),
combine(null, root2.right));
else // root1 != null
if (root2 == null)
return new IntTreeNode(1, combine(root1.left, null),
combine(root1.right, null));
else
return new IntTreeNode(3, combine(root1.left, root2.left),
combine(root1.right, root2.right));
}
1 public header (must be IntTree)
1 private header passing two IntTreeNodes and returns an IntTreeNode (or at
least once they construct an IntTreeNode that is passed as a third parameter)
1 constructs IntTree in public
1 call on private method passing both trees and return IntTree from public
(okay to return an IntTreeNode if that's what they said in their public
header)
3 constructs nodes in the private method
1 attempt
2 always constructed when needed and linked into new tree (-1 if close)
2 root1 == null, root2 == null case
1 attempt (requires test)
1 correct (returns null)
4 root1 == null, root2 != null case
1 attempt (requires test)
1 set root data to 2
2 correct assuming node has been constructed
4 root1 != null, root2 == null case
1 attempt (requires test)
1 set root data to 1
2 correct assuming node has been constructed
3 root1 != null, root2 != null case
1 attempt (requires test)
1 set root data to 3
1 correct assuming node has been constructed
Problem #7
Solution:
public void reorder() {
if (front != null) {
ListNode current = front;
while (current.next != null) {
if (current.next.data < 0) {
ListNode temp = current.next;
current.next = current.next.next;
temp.next = front;
front = temp;
} else
current = current.next;
}
}
}
1 header
1 works (does nothing) for empty list
1 works (does nothing) for 1-element list
4 loop
1 assign a current to front
1 loop while current != null or current.next != null
2 somewhere in loop, current = current.next
5 test for negative
1 attempt at test (generous--might be comparing against front.data or
comparing two adjacent values to see if second > first)
2 correct test (.data < 0 or .data <= front.data)
2 test is "one ahead" (comparing current.next.data or comparing
current.data with a prev)
8 move negatives to front of list (requires negative attempt)
2 correctly removes negative node:
current.next = current.next.next
prev.next = current.next
or equivalent
2 stores negative in a temp prior to removing (prev can be temp)
4 negative moved to front of list (could be put in a separate list and
added to front of the list after loop)
2 attempt (requires front = )
2 correct
Stuart Reges
Last modified: Fri Sep 16 16:16:07 PDT 2011