Skip to main content

Section 21.14 Merge Algorithms

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.

Subsection 21.14.1 Max and Min

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.
Here is the function signatures for the two versions of max_element (min_element is similar):
It max_element( It first, It last );

It max_element( It first, It last, Compare comp );
Listing 21.14.1.
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.

Subsection 21.14.2 Accumulate

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.
The function signature for accumulate looks like:
T accumulate( It first, It last, T init, BinaryOp op );
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:
  1. Start with an accumulated value of 0 (the initial value)
  2. Add 3 to the accumulated value (0 + 3 = 3)
  3. Add 7 to the accumulated value (3 + 7 = 10)
  4. Add 2 to the accumulated value (10 + 2 = 12)
  5. Add 9 to the accumulated value (12 + 9 = 21)
  6. Return the final accumulated value of 21
Listing 21.14.2.
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>.
Going even further, the plus operation is the default for accumulate. So we could even just completely omit the 4th parameter.
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.
Listing 21.14.3.
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:
Listing 21.14.4.

Checkpoint 21.14.1.

Which describes the lambda function that max_element expects to be given?
  • A function that takes two parameters and returns true if the first parameter is greater than the second parameter.
  • A function that takes two parameters and returns true if the first parameter is less than the second parameter.
  • A function that takes one parameter and returns true if that parameter is the maximum value.
  • A function that takes no parameters and returns the maximum value.

Checkpoint 21.14.2.

You have attempted of activities on this page.