【问题标题】:Accumulate Every Other Element in a Vector C++累积向量 C++ 中的所有其他元素
【发布时间】:2019-10-31 03:35:48
【问题描述】:

我希望能够使用累积来累积向量中的每一对元素。我尝试了以下但没有成功,返回一个非空、非零向量的错误

return std::accumulate(vec.begin(), vec.end(), 0,
      [&](int runningSum, int first, int second)
      {return runningSum = runningSum + min(first, second);});

我现在意识到可能不会在对之间获得最小值。例如,如果我有

vector<int> vec = {1,4,2,3} 

我想返回 0 + min(1, 4) + min(2, 3)。

另一方面,是否有任何网站包含许多这些 STL 内置程序的示例?我在网上找到的例子很少。我真的很想看到积累的力量,并适应它。

【问题讨论】:

  • cplusplus.com, cppreference.com
  • @SeverinPappadeux cplusplus.com 通常被认为是一个不好用的网站,坚持使用 cppreference.com

标签: c++ accumulate


【解决方案1】:

std::accumulate() 不允许您使用具有 3 个参数的谓词,只有 2 个参数 - 当前运行的总和,以及要添加到该总和的当前元素。为每个单独的元素调用谓词,并期望返回更新后的总和。

如果你想成对求和,你可以试试这样的方法:

vector<int> vec = {1,4,2,3};
...
int *first = nullptr;
return std::accumulate(vec.begin(), vec.end(), 0,
    [&](int runningSum, int &value) {
        if (first) {
            runningSum += std::min(*first, value);
            first = nullptr;
        } else {
            first = &value;
        }
        return runningSum;
    }
);

更好的解决方案是简单地将您的vector 更改为将一对ints(如std::pair&lt;int, int&gt;)作为其元素类型(或至少将您的向量ints 复制到第二个@987654329 @ of pair),然后您可以按原样累积对:

vector<pair<int,int>> vec = {{1,4},{2,3}};
...
return std::accumulate(vec.begin(), vec.end(), 0,
    [](int runningSum, const pair<int, int> &p) {
        return runningSum + std::min(p.first, p.second);
    }
);

【讨论】:

    【解决方案2】:

    我认为直接使用累积来按对的最小值求和是很困难的。您可能需要先拆分现有向量,然后将它们转换为分钟向量,然后您可以使用累积函数。

    考虑到这一点,我可能会这样做:

        std::vector<int> v{ 1,4,2,3};
        std::vector<int> v2;
        std::vector<int> v3;
        std::vector<int> v4;
    
        std::partition_copy(begin(v),
                            end(v),
                            back_inserter(v2),
                            back_inserter(v3),
                            [toggle = false](int) mutable { return toggle = !toggle; });
    
        std::transform(begin(v2), end(v2), begin(v3), std::back_inserter(v4), [](auto a, auto b)
        {
            return std::min(a,b);
        });
    
        auto sum_of_min_in_pairs =  std::accumulate(begin(v4), end(v4), 0);
    

    请注意,如果您的向量没有偶数数量的元素,上面的代码将会出现问题。否则,将其转换为一对,使用一些默认值来匹配其余部分,具体取决于您想要实现的目标。

    有了 STL 网站,cppreference.com 就是您的朋友。还有一些我强烈推荐的书。

    • Scott Meyers 的《Effective STL》
    • Nicolai Josuttis 的 C++ 标准库

    【讨论】:

      【解决方案3】:

      我会使用std::adjacent_differencestd::accumulate 来解决这个问题:

      #include <algorithm> // std::min
      #include <iostream>
      #include <numeric>   // std::adjacent_difference, std::accumulate
      #include <vector>
      
      int main()
      {
        std::vector v{1, 4, 3, 2, 3, 8, 5, 1};
        std::adjacent_difference(
            v.cbegin(), v.cend(), v.begin(),
            [](auto lhs, auto rhs) { return std::min(lhs, rhs); });
        auto is_second_elem{true};
        std::cout << std::accumulate(cbegin(v), cend(v), 0,
                                     [&is_second_elem](auto acc, auto min) {
                                       is_second_elem = not is_second_elem;
                                       return is_second_elem ? (acc + min) : acc;
                                     })
                  << '\n'; // 7
      }
      

      【讨论】:

        猜你喜欢
        • 2012-11-07
        • 1970-01-01
        • 2016-03-13
        • 2020-11-12
        • 1970-01-01
        • 2021-10-04
        • 1970-01-01
        • 1970-01-01
        • 2021-08-30
        相关资源
        最近更新 更多