Task: Averages_Mode


C++: #include <iterator>
#include <utility>
#include <algorithm>
#include <list>
#include <iostream>


template<typename T> struct referring
{
  referring(T const& t): value(t) {}
  template<typename Iter>
   bool operator()(std::pair<Iter, int> const& p) const
  {
    return *p.first == value;
  }
  T const& value;
};









template<typename FwdIterator, typename OutIterator>
 void mode(FwdIterator first, FwdIterator last, OutIterator result)
{
  typedef typename std::iterator_traits<FwdIterator>::value_type value_type;
  typedef std::list<std::pair<FwdIterator, int> > count_type;
  typedef typename count_type::iterator count_iterator;

  
  count_type counts;

  while (first != last)
  {
    count_iterator element = std::find_if(counts.begin(), counts.end(),
                                          referring<value_type>(*first));
    if (element == counts.end())
      counts.push_back(std::make_pair(first, 1));
    else
      ++element->second;
    ++first;
  }

  
  int max = 0;
  for (count_iterator i = counts.begin(); i != counts.end(); ++i)
    if (i->second > max)
      max = i->second;

  
  for (count_iterator i = counts.begin(); i != counts.end(); ++i)
    if (i->second == max)
      *result++ = *i->first;
}


int main()
{
  int values[] = { 1, 2, 3, 1, 2, 4, 2, 5, 2, 3, 3, 1, 3, 6 };
  median(values, values + sizeof(values)/sizeof(int),
         std::ostream_iterator<int>(std::cout, " "));
  std::cout << std::endl;
  return 0;
}









Fortran: program mode_test
  use Qsort_Module only Qsort => sort
  implicit none

  integer, parameter    :: S = 10
  integer, dimension(S) :: a1 = (/ -1, 7, 7, 2, 2, 2, -1, 7, -3, -3 /)
  integer, dimension(S) :: a2 = (/  1, 1, 1, 1, 1, 0, 2, 2, 2, 2 /)
  integer, dimension(S) :: a3 = (/  0, 0, -1, -1, 9, 9, 3, 3, 7, 7 /)

  integer, dimension(S) :: o
  integer               :: l, trash

  print *, stat_mode(a1)

  trash = stat_mode(a1, o, l)
  print *, o(1:l)
  trash = stat_mode(a2, o, l)
  print *, o(1:l)
  trash = stat_mode(a3, o, l)
  print *, o(1:l)

contains

  
  
  
  
  
  
  integer function stat_mode(a, others, otherslen, ok)
    integer, dimension(:), intent(in) :: a
    logical, optional, intent(out)    :: ok
    integer, dimension(size(a,1)), optional, intent(out) :: others
    integer, optional, intent(out)    :: otherslen

    
    
    
    integer, dimension(size(a, 1)) :: ta, freq, idx
    integer                        :: rs, i, tm, ml, tf

    if ( present(ok) ) ok = .false.

    select case ( size(a, 1) )
    case (0)  
       return
    case (1)
       if ( present(ok) ) ok = .true.
       stat_mode = a(1)
       return
    case default
       if ( present(ok) ) ok = .true.
       ta = a         
       call sort(ta)  
       freq = 1
       idx = 0
       rs = 1         
       
       do i = 2, size(ta, 1)
          if ( ta(i-1) == ta(i) ) then
             freq(rs) = freq(rs) + 1
          else
             idx(rs) = i-1
             rs = rs + 1
          end if
       end do
       idx(rs) = i-1
         
       ml = maxloc(freq(1:rs), 1)  
       tf = freq(ml)               
       tm = ta(idx(ml))            

       
       if ( present(others) ) then
          i = 1
          others(1) = tm
          do
             freq(ml) = 0
             ml = maxloc(freq(1:rs), 1)
             if ( tf == freq(ml) ) then 
                i = i + 1               
                others(i) = ta(idx(ml))
             else
                exit
             end if
          end do
                
          if ( present(otherslen) ) then
             otherslen = i
          end if

       end if
       stat_mode = tm
    end select

  end function stat_mode

end program mode_test