john said:
Hi
I'm a learner and I'm trying to work out the simplest way of finding
the maximum and minimum value from a group of integers.
Any help would be appreciated.
John
Below you'll find an STL algorithm look-alike that does the job.
The trick with most of these search for min, max or both is that in the
limiting case of one element, that element is the min and max this
implies that setting the min and max to the first element in the search
leaves the main algorithm simplier in having to deal with that case.
Returning values from the find_min_max algorithm is trickier in that it
is preferable to not limit the utility of the function template. This
leads to returning "iterators" (or pointers) since the objects may not
be copy-constructible. Also, if the object is large and costly to copy,
it is preferable that an iterator or a pointer is returned.
Below there are 2 find_min_max() functions, one that returns a struct
containing results and one that sets parameters to the min and max.
These methods should be easily inlineable which means this should be as
fast or faster than hand-written code.
template <typename w_value_t>
struct pair_return
{
bool found;
w_value_t first;
w_value_t second;
pair_return()
: found( false )
{
}
pair_return( w_value_t l_first, w_value_t l_second )
: found( true ),
first( l_first ),
second( l_second )
{
}
};
template <typename w_iterator_t >
pair_return<w_iterator_t> find_min_max(
w_iterator_t i_begin,
w_iterator_t i_end
)
{
if ( i_begin == i_end )
{
return pair_return<w_iterator_t>();
}
w_iterator_t l_min_iter = i_begin;
w_iterator_t l_max_iter = i_begin;
for ( ++ i_begin; i_begin != i_end; ++ i_begin )
{
if ( ( * l_max_iter ) < ( * i_begin ) )
{
l_max_iter = i_begin;
}
else if ( ( * i_begin ) < ( * l_min_iter ) )
{
l_min_iter = i_begin;
}
}
return pair_return<w_iterator_t>( l_min_iter, l_max_iter );
}
template <typename w_iterator_t, typename w_value_t>
bool find_min_max(
w_iterator_t i_begin,
w_iterator_t i_end,
w_value_t & o_min_val,
w_value_t & o_max_val
)
{
pair_return<w_iterator_t> ret_val = find_min_max( i_begin, i_end );
if ( ! ret_val.found )
{
return false;
}
o_min_val = * ret_val.first;
o_max_val = * ret_val.second;
return true;
}
//
// test code.
//
int vals[] = { 4, 2, 5, 2 };
int val2[] = { 4 };
#define NELEM( X ) ( sizeof(X)/sizeof(*X) )
#include <iostream>
template <typename w_value_t>
void pair_out( const pair_return< w_value_t > & v )
{
if ( v.found )
{
std::cout << "min = " << * v.first
<< " max = " << * v.second << "\n";
}
else
{
std::cout << "list empty\n";
}
}
int main()
{
pair_return<int *> t1 = find_min_max( vals, vals + NELEM( vals ) );
pair_out( t1 );
pair_return<int *> t2 = find_min_max( vals, vals );
pair_out( t2 );
pair_return<int *> t3 = find_min_max( vals, vals + 1 );
pair_out( t3 );
int min;
int max;
if ( find_min_max( vals, vals + NELEM( vals ), min, max ) )
{
std::cout << "min = " << min << " max = " << max << "\n";
}
}