我有一个关于使用 C++11 或 C++14 迭代向量切片/范围的最佳方法是什么的问题。假设我们有一个
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
的所有元素,以将它们映射到另一个向量。
我可以通过迭代向量、提取子向量并将其传递给 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);
end != v.end();
++begin, ++end) {
std::vector<int> v_slice(begin, end);
v_out.push_back(foo(v_slice));
}
}
上面的方法可行,但它不仅需要大量的样板代码,而且还不必要地复制元素。
我想知道 C++ 是否提供了任何巧妙的方法来轻松迭代向量元素的切片/范围,这些元素可以传递给
std::transform
或 std::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}
};
欢迎任何意见。
使用
std::transform
,您可能会这样做:
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); });
}