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)
|