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

Accumulate Every Other Element in a Vector C++

我希望能够使用 accumulate 对向量中的每隔一对元素进行累加。我尝试了以下但没有成功,returning 一个非空、非零向量的错误

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} 

我想要 return 0 + min(1, 4) + min(2, 3).

另一方面,是否有任何网站包含这些 STL 内置函数的许多示例?我在网上找到的例子很少。很想见识一下积累的力量,好好体会一下。

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

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

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>)作为其元素类型(或至少复制您的向量 ints 到第二个 vector 对),然后你可以按原样累积对:

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);
    }
);

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

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

    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++ 标准库

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