c++ - std 中是否有折叠算法(或失败 : boost) available?

标签 c++ algorithm c++17 fold accumulate

一个非常简单的例子是乘法——假设我有一个 vector :

std::vector<int> ints = {1,2,3,4};

通过一种天真的方法,我可以只使用 std::accumulate(或 std::reduce),它看起来像这样:

int result = std::accumulate(ints.begin(), ints.end(), int{}, [](const int &a, const int &b){return a*b;});

但由于初始值为零 - 结果也变为零(对于这种特定情况,我可以解决它的一种方法是将“1”作为初始值)。

我宁愿使用执行上述操作但没有初始值“副作用”的算法(即,只需将 vector 中的数字相乘)。

字符串处理中经常会遇到类似的问题,其中必须在 元素之间插入定界符。

最佳答案

你所说的可以重新定义为 accumulate 对你范围的最后 N-1 个元素的概括,第一个元素是初始值.

所以你可以这样写:

std::accumulate(std::next(std::begin(ints)), std::end(ints), *std::begin(ints), OP);

不过,您必须假设 ints 是非空的,这提出了我的要点:当范围为空时,假设的标准函数应该返回什么?它的结果应该只是不确定的吗?这样合理吗?

(current draft) 237) accumulate is similar to the APL reduction operator and Common Lisp reduce function, but it avoids the difficulty of defining the result of reduction on an empty sequence by always requiring an initial value

Accumulate 回避了这个问题,并且按照它的方式做事,提供了大量的灵 active 。我认为这是一件好事。

结合为您在整个范围内的操作简单地提供适当的初始值(如 1)的能力,我不相信标准中有太多需要这个假设的替代方案。

可能也很难为它想出两个名称来反射(reflect)已经不对称命名的“accumulate”和“reduce”。


template <class InputIt, class T, class BinaryOperation>
T fold_if_you_really_want_to(InputIt first, InputIt last, BinaryOperation op)
{
    // UB if range is empty. Whatevs.
    T init = *first;
    return std::accumulate(++first, last, std::move(init), std::move(op));
}

……或者类似的东西。请注意,这必然会复制第一个元素;如果你不懒惰,你可以像我一样通过调用 std::accumulate 来避免这种情况。 😊

关于c++ - std 中是否有折叠算法(或失败 : boost) available?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57591199/

相关文章:

algorithm - 制作用于查找所有可能排列的算法

c++ - 涉及STL排序算法的令人困惑的SegFault

c++ - 从初始化列表中推导构造函数的模板参数

c++17 有效地将参数包参数与 std::array 元素相乘

c++ - std::cout 和 printf 数组

c++ - 在编译时推导二维数组的一维

c# - 平台独立性: How is it different from moving source code from one OS to another?

C++ "Building a series to solve a function"为什么我的近似值不对?

algorithm - TSP - 分支定界

c++ - 为什么 const vector<const pair<...>> 给出 'cannot be overloaded' 错误?