Search code examples
c++lambdaaccumulate

How can I use std::accumulate and a lambda to calculate a mean?


I have a standard library container of large numbers, so large that they may cause overflow if I add them together. Let's pretend it's this container:

std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

I want to calculate the mean of this container, using std::accumulate, but I can't add all the numbers together. I'll just calculate it with v[0]/v.size() + v[1]/v.size() + .... So I set:

auto lambda = ...;
std::cout << std::accumulate(v.begin(), v.end(), 0, lambda) << std::endl;

Here is what I have tried so far, where -> indicates the output:

lambda = [&](int a, int b){return (a + b)/v.size();};  ->  1
lambda = [&](int a, int b){return a/v.size() + b/v.size();};  ->  1
lambda = [&](int a, int b){return a/v.size() + b;};  ->  10

How can I produce the correct mean such that the output will be 5?


Solution

  • You shouldn't use integer to store the result:

    The return type passed to the function accumulate:
    T accumulate( InputIt first, InputIt last, T init, BinaryOperation op ); depends on the third parameter type: (T init) so you have to put there: 0.0 to get result as double.

    #include <vector>
    #include <algorithm>
    #include <iostream>
    #include <numeric>
    using namespace std;
    std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    
    int main()
    {
        auto lambda = [&](double a, double b){return a + b / v.size(); };
        std::cout << std::accumulate(v.begin(), v.end(), 0.0, lambda) << std::endl;
    }