Averages/Mode: Difference between revisions
Line 7: | Line 7: | ||
public class Mode { |
public class Mode { |
||
public static <T> List<T> mode(List<T> coll) { |
public static <T> List<T> mode(List<? extends T> coll) { |
||
Map<T, Integer> seen = new HashMap<T, Integer>(); |
Map<T, Integer> seen = new HashMap<T, Integer>(); |
||
int max = 0; |
int max = 0; |
Revision as of 08:36, 14 June 2009
You are encouraged to solve this task according to the task description, using any language you may know.
Write a program to find the mode value of a vector of integers. The case where the vector is empty may be ignored. Care must be taken to handle the case where the mode is non-unique.
Java
<lang java>import java.util.*;
public class Mode {
public static <T> List<T> mode(List<? extends T> coll) { Map<T, Integer> seen = new HashMap<T, Integer>(); int max = 0; List<T> maxElems = new ArrayList<T>(); for (T value : coll) { if (seen.containsKey(value)) seen.put(value, seen.get(value) + 1); else seen.put(value, 1); if (seen.get(value) > max) { max = seen.get(value); maxElems.clear(); maxElems.add(value); } else if (seen.get(value) == max) { maxElems.add(value); } } return maxElems; }
public static void main(String[] args) { System.out.println(mode(Arrays.asList(1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17))); // prints [6] System.out.println(mode(Arrays.asList(1, 1, 2, 4, 4))); // prints [1, 4] }
}</lang>
Octave
Of course Octave has the mode function; but it returns only the "lowest" mode if multiple modes are available.
<lang octave>function m = mode2(v)
sv = sort(v); % build two vectors, vals and c, so that % c(i) holds how many times vals(i) appears i = 1; c = []; vals = []; while (i <= numel(v) ) tc = sum(sv==sv(i)); % it would be faster to count % them "by hand", since sv is sorted... c = [c, tc]; vals = [vals, sv(i)]; i += tc; endwhile % stack vals and c building a 2-rows matrix x x = cat(1,vals,c); % sort the second row (frequencies) into t (most frequent % first) and take the "original indices" i ... [t, i] = sort(x(2,:), "descend"); % ... so that we can use them to sort columns according % to frequencies nv = x(1,i); % at last, collect into m (the result) all the values % having the same bigger frequency r = t(1); i = 1; m = []; while ( t(i) == r ) m = [m, nv(i)]; i++; endwhile
endfunction</lang>
<lang octave>a = [1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]; mode2(a) mode(a)
a = [1, 1, 2, 4, 4]; mode2(a) % returns 1 and 4 mode(a) % returns 1 only</lang>
Python
<lang python>>>> from collections import defaultdict >>> def modes(values): count = defaultdict(int) for v in values: count[v] +=1 best = max(count.itervalues()) return [k for k,v in count.iteritems() if v == best]
>>> modes([1,3,6,6,6,6,7,7,12,12,17]) [6] >>> modes((1,1,2,4,4)) [1, 4]</lang>
Ruby
Here's two methods, the first more Ruby-ish, the second perhaps a bit more efficient. <lang ruby>def mode(ary)
seen = Hash.new(0) ary.each {|value| seen[value] += 1} max = seen.values.max seen.find_all {|key,value| value == max}.map {|key,value| key}
end
def mode_one_pass(ary)
seen = Hash.new(0) max = 0 max_elems = [] ary.each do |value| seen[value] += 1 if seen[value] > max max = seen[value] max_elems = [value] elsif seen[value] == max max_elems << value end end max_elems
end
p mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]) # => [6] p mode([1, 1, 2, 4, 4]) # => [1, 4] p mode_one_pass([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]) # => [6] p mode_one_pass([1, 1, 2, 4, 4]) # => [1, 4]</lang>
Tcl
<lang tcl># Can find the modal value of any vector of values proc mode {n args} {
foreach n [list $n {*}$args] { dict incr counter $n } set counts [lsort -stride 2 -index 1 -decreasing $counter] set best {} foreach {n count} $counts { if {[lindex $counts 1] == $count} { lappend best $n } else break } return $best
}
- Testing
puts [mode 1 3 6 6 6 6 7 7 12 12 17]; # --> 6 puts [mode 1 1 2 4 4]; # --> 1 4</lang>