C ++将常数添加到向量切片

时间:2019-05-01 09:03:13

标签: c++ vector addition

我知道使用transform可以像这样向某些向量添加常量:

std::vector<int> a(3, 2);
std::transform( a.begin(), a.end(), a.begin(), std::bind2nd( std::plus<double>(), 1 ) );

我想知道如何修改transform以向向量的某个切片[index:end]添加常量,例如最后两个元素。

我可以循环执行,例如:

for (int i=1; i < a.size(); i++) {
    a.at(i) += 1;
}

但也许有更好的选择

4 个答案:

答案 0 :(得分:2)

最后N个元素?使用反向迭代器:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main() {
  std::vector<int> a(3, 2);
  std::transform(a.rbegin(), std::next(a.rbegin(), 2), a.rbegin(),
                 [](auto n) { return n + 1; });

  for (auto n : a) {
    std::cout << n << '\n';
  }
  return 0;
}

(如果由于某种原因需要将std::next()更改为没有随机迭代器的容器类型,使用a.rbegin() + 2而不是a会更容易。)

答案 1 :(得分:2)

算法采用迭代器而不是容器的原因正是针对这种情况。

适应Python样式片的一般方法是将+ve值添加到begin,将-ve添加到end。假设至少有两个元素,则将最后两个元素递增为

auto start = a.end() - 2;
auto finish = a.end();
std::transform( start, finish , start, std::bind2nd( std::plus<double>(), 1 ) );

答案 2 :(得分:1)

少量重构后的相同代码:

std::vector< int > a(3, 2);

auto start = a.begin();
auto end   = a.end();
auto func  = [](auto val) {
    return val + 1;
};

std::transform(start, end, start, func);

现在,通过修改startend的值,只能修改切片。

为此std::advance可以使用:

std::advance(start, 1);
std::advance(end, -1);

在上面的代码中:

  • start在开头之后是1个元素(第二个元素-索引为1的元素)。
  • end从头算起是1个元素。

答案 3 :(得分:1)

您可以使用跨度(在C ++ 20中为std::span,之前为gsl::span)来表示切片。如果您不了解跨度,请查看:

What is a "span" and when should I use one?

所以如果你写,

// ... vector a gets defined
auto slice = std::span(a).subspan(some_index);

现在,切片的行为就像任何标准库容器一样。具体来说,您可以这样写:

std::transform(slice.begin(), slice.end(), slice.begin(), [](auto v) { return v + 1; });
相关问题