Assume I have an array of doubles that looks like the following:
Array[10] = {10, 10, 10, 3, 10, 10, 6, 10, 10, 9, 10}
I need a function th
As @Grizzly points out, doubles are problematic from a computational standpoint. I would also suggest that they don't make sense from the standpoint of your problem domain; doubles don't make any sense with majority voting!
So lets assume that 10
and 6
and so on are integer identifiers for the things people are voting for. Lets also assume that you know that users can vote any value from 0
to 10
.
int[] votes = ...
int[] voteCounts = new int[11]; // 11 could be calculated ...
for (int vote : votes) {
voteCounts[vote]++;
}
int majority = (votes.length + 1) / 2;
for (int i = 0; i < voteCounts.length; i++) {
if (voteCounts[i] >= majority) {
return i; // the winner!
}
}
throw new NoClearMajorityException(...);
This algorithm is O(N)
in time and O(M)
in space, where M is the largest identifier. The catch is that it only works (as written) if the identifiers are integers.
You could do this: Convert your array to a list and sort it. Pick the first index, and call lastIndexOf(obj) on the value. Do this for each new value you encounter, calculate the range of the value and store the results of the biggest range in a variable.
With an array of doubles this might not be easy since equality comparisons on doubles are pretty problematic. If you can get away with using integers, you can do something like the following:
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int element: Array)
{
Integer frequency = map.get(element);
map.put(element, (frequency != null) ? frequency + 1 : 1);
}
int mostFrequentItem = 0;
int[] maxFrequencies = new int[2];
maxFrequencies[0] = Integer.MIN_VALUE;
for(Entry<Integer, Integer> entry: map.entrySet())
{
if(entry.getValue()>= maxFrequencies[0])
{
mostFrequentItem = entry.getKey();
maxFrequencies[1] = maxFrequencies[0];
maxFrequencies[0] = entry.getValue();
}
}
if(maxFrequencies[1] == maxFrequencies[0])
throw new Exception();//insert whatever exception seems appropriate
return mostFrequentItem
This will have O(n) performance, so it should be pretty optimal in asymptotic performance behaviour. If your doubles are not the results of calculations but come from an other source, that is if you can be sure that values which are basically the same will be represented equally, you might get away with using the same method for doubles, however I would still recommend being careful that this is really the case.
Edit: some performance improvements as suggested in the comment as well as supporting checking for ambiguous case