1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
#include <iostream>
#include <cassert>
#include <vector>
#include <algorithm>
// return the number of consecutive occurrences of the values starting at first
std::size_t frequency_of( const int* first, const int* end )
{
// pointer to the first element that is greater than the current value
// http://en.cppreference.com/w/cpp/algorithm/upper_bound
const int* next = std::upper_bound( first, end, *first ) ;
return next - first ;
}
// return the the highest frequency for any value in [begin,end)
// invariant: the sequence [begin,end) is sorted in ascending order
std::size_t max_frequency( const int* begin, const int* end )
{
assert( std::is_sorted(begin,end) ) ; // assert the invariant
std::size_t max_so_far = 0 ;
const int* curr = begin ; // start with the first value ;
while( curr != end )
{
const std::size_t frequency_of_this_value = frequency_of( curr, end ) ;
max_so_far = std::max( max_so_far, frequency_of_this_value ) ;
curr += frequency_of_this_value ; // repeat for the next value
}
return max_so_far ;
}
std::vector<int> find_mode( int data[], std::size_t size )
{
std::vector<int> result ;
int* begin = data ; // beginning of the sequence ;
int* end = data + size ; // end of the sequence ;
// 1. sort the values in ascending order
std::sort( begin, end ) ;
// 2. Iterate (loop) through the array to find out what the highest frequency
// for any value is without worrying about storing any of the values.
const std::size_t frequency_of_mode = max_frequency( begin, end ) ;
// 3. Iterate through the array again, this time comparing the counts for each value
// to the highest frequency that you already found, if the count for a value is
// the same as the highest frequency, push that value into your results vector.
const int* curr = begin ; // start with the first value ;
while( curr != end )
{
const std::size_t frequency_of_this_value = frequency_of( curr, end ) ;
if( frequency_of_this_value == frequency_of_mode ) result.push_back(*curr) ;
curr += frequency_of_this_value ;
}
return result ;
}
int main()
{
const std::size_t N = 20 ;
int data[N] = { 8, 0, 7, 0, 5, 3, 1, 8, 7, 1, 5, 8, 3, 1, 7, 1, 5, 3, 7, 8 };
for( int v : find_mode( data, N ) ) std::cout << v << ' ' ;
std::cout << '\n' ;
}
|