累积向量C ++中的所有其他元素

时间:2019-10-31 03:35:48

标签: c++ accumulate

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

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的示例?我在网上找到的例子很少。我真的很想看到积累的力量,并对此感到满意。

3 个答案:

答案 0 :(得分:3)

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以将一对int(例如std::pair<int, int>)作为元素类型(或至少复制向量{{1 }}到第二对int对,然后您可以按原样累积对:

vector

答案 1 :(得分:0)

我认为仅使用立即累积来对最小对进行求和将很困难。您可能需要先拆分现有向量,然后将其转换为分钟向量,然后才能使用累加函数。

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

    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的有效STL
  • Nicolai Josuttis的C ++标准库

答案 2 :(得分:0)

我会使用 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
}