The final category of algorithms we will look at examples for are algorithms that merge or combine collections.These algorithms take a collection of data and produce a single value from it.
max_element and min_element find the largest and smallest elements in a collection, respectively. Like find, they return an iterator pointing to the found element.
By default, both algorithms use the less-than operator to compare elements. (Having max use < and then just reverse the results of the comparison means that we only need to overload one operator to use both the max and min algorithms.) However, we can provide a custom comparator if we want to change the criteria for comparison.
Notice that the lambda function we give to the max_element algorithm compares a and b and returns true if a is shorter than b. This is the logic of βless thanβ. Both max and min expect us to use the same logic in a comparison function: we should take two items and return true if the first is less than the second, and false otherwise.
If you change the call to min_element instead of max_element, the program will find the shortest word instead of the longest using the same comparison function.
Another common merging operation is to compute a total or sum of all the items in a collection. The accumulate algorithm from <numeric> does just that. It takes a range of items and an initial value, and it adds up all the items in the range, starting from the initial value.
As expected, first and last define the range of items to process. The init parameter is the initial value to start the accumulation from. The op parameter is a binary operation that takes two parameters: the current accumulated value and the next item from the collection. It should return the new accumulated value.
Say we have a vector of integers: {3, 7, 2, 9}. And we want to add them up. We could call accumulate and give it an initial value of 0 and a lambda function that adds two numbers together. Then it would do the following:
Start with an accumulated value of 0 (the initial value)
It is a little silly to write a lambda function that just adds two numbers together. To prevent that, the standard library provides a function object called std::plus in the <functional> header that does exactly that. We could write the above code using this syntax:
#include <functional>
// ...
int sum = accumulate(
numbers.begin(),
numbers.end(),
0,
std::plus<int>()
);
Here, we use the std::plus function object instead of writing a lambda function that adds two numbers together. Notice that we have to say what kind of data it operates on by specifying the template parameter <int>.
In addition to plus, the C++ Functional library provides operations like std::multiplies for multiplication, std::minus for subtraction, and std::divides for division. It also provides comparison operations like std::less and std::greater.
If we wanted to multiply those same numbers, we would specify an initial value of 1 (so that the initial value times the first number is the first number) and a lambda function that multiplies two numbers together.
We could also use accumulate to concatenate a list of strings. We would specify an initial value of the empty string ("") and a lambda function that concatenates two strings together. Since the default behavior of accumulate is to add things together, and the + operator for strings does concatenation, we could even omit the lambda function and just do: