C++将元素乘在一个向量中

C++ Multiplying elements in a vector

本文关键字:一个 向量 元素 C++      更新时间:2023-10-16

我一直在寻找以下问题的更优化解决方案,但似乎找不到。

假设我有一个向量:

std::vector<double> vars = {1, 2, 3}

我想执行1 * 2 * 3我知道我可以做以下事情:

int multi = 1;
for(int i = 0; (i < vars.size()-1); i++)
{
    multi *= vars[i];
}

但是,有没有一种更"C++11"的方法可以做到这一点?我真的很想用lambda来做这件事,这样我就可以计算向量的乘积,而不需要在类中有另一个函数,我宁愿在函数中计算它。

是的,和往常一样,有一个算法(尽管这个算法在<numeric>中),std::accumulate(实际示例):

using std::begin;
using std::end;
auto multi = std::accumulate(begin(vars), end(vars), 1, std::multiplies<double>());

std::multiplies也在<functional>中。默认情况下,std::accumulate使用std::plus,它将给operator()的两个值相加。CCD_ 11是一个将它们相乘的函子。

在C++14中,您可以用std::multiplies<>替换std::multiplies<double>operator()是模板化的,它将计算出类型。根据我在Eric Niebler的Ranges提案中看到的情况,它可能稍后看起来像vars | accumulate(1, std::multiplies<>()),但对此持保留态度。

您可以使用基于范围的for循环,如:

std::vector<double> vars = {1, 2, 3}
int multi = 1;
for (const auto& e: vars)
    multi *= e;

另一种方法是使用inclusive_scan(C++17及以上版本)

优点是你可以得到第一个"的倍数;N〃;向量中的元素。下面是代码。注释中的解释。

#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main()
{
    //INPUT VECTOR
    std::vector<int> data{ 3, 1, 4, 1, 5, 9, 2, 6 };
    //OUTPUT VECTOR WITH MULTIPLIES
    //FIRST ELEMENT - 3 
    //SECOND ELEMENT - 3 * 1 
    //THIRD ELEMENT - 3 * 1 * 4 
    //FOURTH ELEMENT - 3 * 1 * 4 * 1
    // ..
    // ..
    //LAST ELEMENT - 3 * 1 * 4 * 1 * 5 * 9 * 2 * 6
    std::vector<int> multiplies(data.size());
    //Multiply all numbers in given vector.
    inclusive_scan(data.begin(), data.end(),
        multiplies.begin(),
        std::multiplies<>{});
    //PRODUCT OF FIRST 5 ELEMENTS.
    std::cout << "Product of first 5 elements :: " << multiplies[4] << std::endl;
    //PRODUCT OF ALL ELEMENTS
    std::cout << "Product of all elements :: " << multiplies[data.size() - 1] << std::endl;
}

此外,还有一个可以指定执行策略的重载。顺序执行或并行执行。需要包括";执行";头球

//MULTIPLY ALL NUMBERS IN VECTOR WITH PARALLEL EXECUTION.
inclusive_scan(std::execution::par,data.begin(), data.end(),
    multiplies.begin(),
    std::multiplies<>{});