Lesson Introduction

Welcome back! In our previous lesson, we explored the fundamentals of STL algorithms in C++ and how they can enhance your code's efficiency and readability. Today, we will continue this journey by diving into more advanced STL algorithms, with a focus on std::accumulate.

By the end of this lesson, you should understand:

  1. How to use std::accumulate to find the sum of numbers in a vector.
  2. Advanced uses of std::accumulate with custom functionalities using lambda expressions.
Understanding `std::accumulate`

std::accumulate in the <numeric> header performs a fold or reduction operation over a range of elements. It combines the elements using a binary operation, starting with an initial value.

The basic syntax of std::accumulate:

std::accumulate(first, last, init);
  • First: Iterator to the beginning of the range.
  • Last: Iterator to the end of the range.
  • Init: Initial value to start the accumulation.
Example of Using `std::accumulate`

Here is an example using std::accumulate to sum the elements of a vector:

#include <iostream>
#include <vector>
#include <numeric>  // For std::accumulate

int main() {
    std::vector<int> data = {1, 2, 3, 4, 5};

    // Using std::accumulate
    int sum = std::accumulate(data.begin(), data.end(), 0);
    std::cout << "Sum: " << sum << '\n';  // Sum: 15

    return 0;
}

Explanation:

  1. Initialize a vector: We initialize a vector data with {1, 2, 3, 4, 5}.
  2. Use std::accumulate: We pass the range defined by data.begin() and data.end(), and the initial value 0.
  3. Result: The function sums the elements starting from 0. The final sum, 15, is outputted.
Advanced Use of `std::accumulate`

Consider computing the product of elements:

#include <iostream>
#include <vector>
#include <numeric>  // For std::accumulate
#include <functional>  // For std::multiplies

int main() {
    std::vector<int> data = {1, 2, 3, 4, 5};

    // Using std::accumulate with std::multiplies
    int product = std::accumulate(data.begin(), data.end(), 1, std::multiplies<int>());
    std::cout << "Product: " << product << '\n';  // Product: 120

    return 0;
}

Explanation:

  1. Initial Value: Use 1 as the initial value.
  2. Custom Operation: Use std::multiplies<int>() for multiplication.
Using Lambda Expressions: Sum of Squares

Let's look at custom logic with lambda expressions.

Finding the Sum of Squares:

#include <iostream>
#include <vector>
#include <numeric>  // For std::accumulate

int main() {
    std::vector<int> data = {1, 2, 3, 4, 5};

    // Using std::accumulate with a lambda expression
    int sum_of_squares = std::accumulate(data.begin(), data.end(), 0, [](int sum, int val) {
        return sum + val * val;
    });
    std::cout << "Sum of Squares: " << sum_of_squares << '\n';  // Sum of Squares: 55

    return 0;
}

Custom Lambda: We pass a lambda that computes the square of each element and adds it to the sum. In the lambda expression:

  • sum: Accumulator that holds the ongoing sum of squares.
  • val: Current element from the vector being processed.
Using Lambda Expressions: Combining Vectors

Combining two vectors into a single accumulated sum:

#include <iostream>
#include <vector>
#include <numeric>  // For std::accumulate

int main() {
    std::vector<int> data1 = {1, 2, 3, 4, 5};
    std::vector<int> data2 = {6, 7, 8, 9, 10};

    // Combining two vectors element-wise and accumulating the result
    int combined_sum = std::accumulate(data1.begin(), data1.end(), 0, [&data2, i = 0](int sum, int val) mutable {
        return sum + val + data2[i++];
    });
    std::cout << "Combined Sum: " << combined_sum << '\n';  // Combined Sum: 55

    return 0;
}

Lambda with Capture: We capture data2 by reference and use a mutable lambda to add elements of both vectors. In the lambda expression:

  • sum: Accumulator that holds the ongoing sum of combined elements from both vectors.
  • val: Current element from data1 being processed.
  • data2[i++]: Corresponding element from data2 being added, with mutable allowing us to modify the captured i to iterate through data2.
Lesson Summary

In this lesson, we explored:

  • The importance and utility of STL algorithms in C++.
  • How to use std::accumulate for simple and complex operations.
  • Examples with built-in and custom operations via lambda expressions.

Now that you've learned to use std::accumulate, it's time to practice. Move on to the hands-on exercises to reinforce your understanding and enhance your skills. Good luck, and happy coding!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal