In C++, we can call the functions min_element() and max_element() to find the elements having respectively the lowest or the highest value in a standard container. These functions belong to the standard std::algorithm library.
For easy of understanding, we can be interested to retrieve not just the smallest or the largest integer of a list, but – for example – also the element having the highest score, priority… or the lowest ID.
The functions min_element() and max_element() can help us to achieve this goal.
#Min_element() and max_element()
These functions requires the input iterators to the initial and final positions of the sequence of elements to compare.
The type of the element can be any of your choice! The most important thing is that you know how the elements stored in the container should be compared among them. If you know how to compare them, you can get the element with highest and lowest value/score.
The functions min_element() and max_element() can process any array/vector/list of elements and return an iterator to the position storing the minimum or maximum value respectively. If the container is empty, then the iterator to the end of the container is returned (i.e., myContainer.end())
#Finding the minimum or the maximum value in C++
#include <iostream> // std::cout
#include <list> // My standard container
#include <algorithm> // std::min_element, std::max_element
bool myfn(int i, int j) { return i<j; }
struct myclass {
bool operator() (int i, int j) { return i<j; }
} myobj;
int main() {
std::list<int> myContainer{ 20, 10, 100, 40, 60, 80, 50 };
// using default comparison:
auto it_min = std::min_element(myContainer.cbegin(), myContainer.cend());
auto it_max = std::max_element(myContainer.cbegin(), myContainer.cend());
std::cout << "The smallest integer is " << *it_min << std::endl;
std::cout << "The largest integer is " << *it_max << std::endl;
// using function myfn as comp:
auto it_min2 = std::min_element(myContainer.cbegin(), myContainer.cend(), myfn);
auto it_max2 = std::max_element(myContainer.cbegin(), myContainer.cend(), myfn);
std::cout << "The smallest integer is " << *it_min2 << std::endl;
std::cout << "The largest integer is " << *it_max2 << std::endl;
// using object myobj as comp:
auto it_min3 = std::min_element(myContainer.cbegin(), myContainer.cend(), myobj);
auto it_max3 = std::max_element(myContainer.cbegin(), myContainer.cend(), myobj);
std::cout << "The smallest integer is " << *it_min3 << std::endl;
std::cout << "The largest integer is " << *it_max3 << std::endl;
return 0;
}
#Min_element() and max_element() with a custom class
#include <iostream> // std::cout
#include <vector> // storing tasks in a vector
#include <algorithm> // std::min_element, std::max_element
struct JobTask
{
int ID;
int priority; // we are interested to the highest and lowest priority tasks
bool operator<(JobTask& a) { return priority < a.priority; }
};
bool myfn(const JobTask& a, const JobTask& b) { return a.ID < b.ID; }
int main() {
std::vector<JobTask> myContainer(10);
// init the vector of 10 elements
for (int i = 0; i < 10; i++)
{
myContainer[i].ID = i * 2;
myContainer[i].priority = 20 - 2 * i;
}
// using default comparison:
auto it_min = std::min_element(myContainer.begin(), myContainer.end() );
auto it_max = std::max_element(myContainer.begin(), myContainer.end() );
std::cout << "The lowest priority is " << it_min->priority <<
" at position " << std::distance(myContainer.begin(), it_min) << std::endl;
std::cout << "The highest priority is " << it_max->priority <<
" at position " << std::distance(myContainer.begin(), it_max) << std::endl;
// using function myfn as comp:
auto it_min2 = std::min_element(myContainer.begin(), myContainer.end(), myfn);
auto it_max2 = std::max_element(myContainer.begin(), myContainer.end(), myfn);
std::cout << "The lowest ID is " << it_min2->ID <<
" at position " << std::distance(myContainer.begin(), it_min2) << std::endl;
std::cout << "The largest ID is " << it_max2->ID <<
" at position " << std::distance(myContainer.begin(), it_max2) << std::endl;
return 0;
}
Have you noticed the operator overload at line 10? We need to specify the sorting criteria to compare the elements of type JobTask.
#Getting both min and max values at the same time in C++
There is more! In C++, the minimum and maximum value in a container can be found in a single line of code using the std::minmax_element() function!
#include <iostream> // std::cout
#include <vector> // storing tasks in a vector
#include <algorithm> // std::min_element, std::max_element, std::minmax_element
struct JobTask
{
int ID;
int priority; // we are interested to the highest and lowest priority tasks
bool operator<(JobTask& a) { return priority < a.priority; }
};
bool myfn(const JobTask& a, const JobTask& b) { return a.ID < b.ID; }
int main() {
std::vector<JobTask> myContainer(10);
// init the vector of 10 elements
for (int i = 0; i < 10; i++)
{
myContainer[i].ID = i * 2;
myContainer[i].priority = 20 - 2 * i;
}
// using default comparison:
auto it = std::minmax_element(myContainer.begin(), myContainer.end());
std::cout << "The lowest priority is " << it.first->priority <<
" at position " << std::distance(myContainer.begin(), it.first) << std::endl;
std::cout << "The highest priority is " << it.second->priority <<
" at position " << std::distance(myContainer.begin(), it.second) << std::endl;
// using function myfn as comp:
auto it2 = std::minmax_element(myContainer.begin(), myContainer.end(), myfn);
std::cout << "The lowest ID is " << it2.first->ID <<
" at position " << std::distance(myContainer.begin(), it2.first) << std::endl;
std::cout << "The largest ID is " << it2.second->ID <<
" at position " << std::distance(myContainer.begin(), it2.second) << std::endl;
return 0;
}
The function std::minmax_element() is similar to the functions above described. The main difference is that this function returns a pair of iterators rather than a single one. The first iterator points to the element having the minimum value, while the second iterator points to the element having the maximum value.
