c++ 如何在std::vector的范围内进行编译

olqngx59  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(91)

我有一个问题,关于用C11或C14对向量的切片/范围进行遍历的最佳方法是什么。假设我们有一个std::vector,它包含一堆值:

std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};

字符串
这个向量用作输入,从n连续值中计算一个值,类似于移动平均。为此,我有一个函数foo,它将n连续元素作为输入,进行一些数学运算,并输出一个值。这意味着这个函数看起来像下面的声明:

int foo(const std::vector<int> &v_range);


我想将foo应用于v的所有元素,将它们Map到另一个向量。我可以通过迭代向量,提取子向量,并将其传递给foo来实现这一点。请参见下面的代码。

// Example program
#include <vector>
#include <iostream>

int foo(const std::vector<int> &v) {
    
    std::cout << "[";
    for(int e: v) {
        std::cout << e << ",";
    }
    std::cout << "]" << std::endl;
    return 0;
}

int main()
{
  std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};
  std::vector<int> v_out;
  std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};
  std::vector<int> v_out;
  const int n = 3;

  for (auto begin = v.begin(), end = std::next(v.begin(), n);
       std::next(begin, n - 1) != v.end();
       ++begin, ++end) {
      std::vector<int> v_slice(begin, end);
      v_out.push_back(foo(v_slice));
  }
}


Demo
上面的工作,但它不仅需要大量的样板代码,但它也不必要地复制周围的元素。
我想知道C是否提供了任何聪明的方法来轻松地对vector的元素的切片/范围进行遍历,这些切片/范围可以传递给std::transformstd::for_each
或者,我想知道C
是否提供了任何方法来将输入向量转换为向量范围的向量,类似于以下伪代码:

std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};

  std::vector<std::vector<int>> v_sliced = { 
    {0,1,2},
    {1,2,3},
    {2,3,4}
    ///...
    {8,9,10}
  };


欢迎任何输入。

pb3skfrl

pb3skfrl1#

使用std::transform,您可能会有std::vector<std::vector<int>>

std::vector<std::vector<int>> sliced_n(const std::vector<int>& v, std::size_t n)
{
    if (v.size() < n) throw std::invalid_argument("");

    std::vector<std::vector<int>> res;

    std::transform(v.begin(), v.end() - n + 1,
                   std::back_inserter(res),
                   [n](auto &e){ return std::vector(&e, &e + n); });
    return res;
}

int main()
{
  std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};
  auto sliced = sliced_n(v, 3);
  std::vector<int> v_out;
  std::transform(sliced.begin(), sliced.end(),
                 std::back_inserter(v_out),
                 [](const auto& v){ return foo(v); });
}

字符串
Demo
但更简单

std::transform(v.begin(), v.end() + 1 - n,
               std::back_inserter(v_out),
               [&](const auto& e){ return foo(std::vector(&e, &e + n)); });


Demo

相关问题