Part
(a) // precondition: each entry in ballotList is a Set representing
// one voter's ballot
// postcondition: voteCount.get(candidate) is the total number of
// times candidate appears on ballots in ballotList
public VoterBallots(List ballotList)
{
voteCount = new HashMap(); 1
Iterator iter = ballotList.iterator();
while(iter.hasNext())
{
Set ballot = (Set)iter.next();
Iterator ballotIter = ballot.iterator(); 2
while (ballotIter.hasNext())
{
String candidate = (String)ballotIter.next();
int count = 0;
Object obj = voteCount.get(candidate);
if (obj != null)
count = ((Integer)obj).intValue();
voteCount.put(candidate, new Integer(count + 1)); 3
}
}
} Notes:
- We could use a
TreeMap as well.
- The outer loop iterates over all the ballots in
ballotList ; the inner loop iterates over all the candidates
in the ballot.
Integer is immutable, so we need to create a new
Integer for the updated count and put it in the map.
If candidate is already in the map, the value associated
with it is replaced.
Part (b) // postcondition: returns a set containing the candidate(s)
// with the most votes
public Set candidatesWithMost()
{
Set bestCandidates = new HashSet(); 1
Iterator iter = voteCount.keySet().iterator();
Integer maxCount = maxVotes();
while(iter.hasNext())
{
Object candidate = iter.next();
Integer count = (Integer)voteCount.get(candidate);
if (count.equals(maxCount)) 2
bestCandidates.add(candidate);
}
return bestCandidates;
} Notes:
- You could pick
TreeSet , but then Part(c) would become
more difficult.
- Not
if (count == maxCount)... because you are comparing
Integer objects. You could use int maxCount = maxVotes().intValue();
...
int count = ((Integer)voteCount.get(candidate)).intValue();
if (count == maxCount) ...
but it is more error-prone.
Part (c)
O(C).
The time of the candidatesWithMost method consists of the
time needed to call maxVotes , the time needed to iterate over
all the candidates (i.e., over all the keys in the voteCount
map), and the time for inserting matching candidates into
bestCandidates . 1
Since voteCounts is a HashMap , the time for
traversing it in the maxVotes method and in the
candidatesWithMost method is O(C).
2 Since bestCandidates is a
HashSet , The time for inserting a candidate into it is
O(1). The total time is O(C). 3
Notes:
- Note that the votes have been already tallied in the constructor, so
the individual voters are no longer represented anywhere and their
number V is irrelevant.
- If
voteCounts were a TreeMap , we'd have to
multiply the traversal time by log C, because each
get(...) call takes O(log C) time.
(You may argue it doesn't have to in a more efficient implementation of
TreeMap traversal by keys, but there is no one to argue
with at the AP exam. It's better to just use a
HashMap to be on the safe side.)
- The time for inserting a candidate into
bestCandidates
may potentially get you bogged down in the issue of what portion of
C can match the best count, and so on. To avoid that, make
bestCandidates a HashSet , so that adding a
value to is always O(1). For a TreeSet , the
total worst-case time (when all the candidates have the same count)
would be O(C log C)
|