使用`transform`创建一个增加的向量

时间:2016-12-12 15:39:01

标签: c++ c++11 std

我正在尝试使用transform制作增加的向量,但不能正确执行。我想用变换。我做错了什么?

PS - 我将使用c ++ 11标准和g ++。

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

int main()
{
    std::vector<double> x(10);
    x.front() = 0.0;
    double h = 0.1;
    std::transform(x.begin(), x.end() - 1, x.begin() + 1, [h](unsigned int xn) {return xn + h;});
    std::cout << x.at(3) << " " << x.at(9) << std::endl;
}

5 个答案:

答案 0 :(得分:5)

转换为unsigned int会在用于计算下一个

时截断每个值

答案 1 :(得分:2)

std::transform - 使用一元运算符

  

std::transform将给定函数应用于范围并存储   导致另一个范围,从d_first开始。

通过std::transform和关闭,您可以初始化std::vector

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

int main() {
  std::vector<double> v(10);
  const double step = 0.1;

  std::transform(begin(v), end(v), begin(v),
                 [step](const double value) { return value + step; });

  for (const auto value : v) {
    std::cout << value << ' ';
  }
}

std::generate - 通过可调用

递增
  

为范围[first,last]中的每个元素指定由...生成的值   给定功能对象

如果您想要自定义增量,可以使用std::generate

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

int main() {
  std::vector<double> v(10);
  double seed = 0.0;

  std::generate(begin(v), end(v), [&seed]() {
    const auto ret = seed;
    seed += 0.1;
    return ret;
  });

  for (const auto value : v) {
    std::cout << value << ' ';
  } // outputs: 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 
}

std::iota - 通过++value增加

稍微偏离主题。您可以提供operator++类型的增量为0.1的类型,但对于读者来说并不直观。

您可以使用依赖operator++。{/ p>的std::iota

  

按顺序增加值填充[first,last]范围,从值开始并重复评估++value

您案例中的代码将是:

#include <numeric>
#include <iostream>
#include <vector>

int main() {
  std::vector<double> v(10);

  std::iota(begin(v), end(v), 0.0);

  for (const auto value : v) {
    std::cout << value << ' ';
  } // outputs: 0 1 2 3 4 5 6 7 8 9
}

答案 2 :(得分:1)

lambda声明了一个错误的参数类型

[h](unsigned int xn) {return xn + h;});
    ^^^^^^^^^^^^^^^

应该有

[h]( double xn ) {return xn + h;});
    ^^^^^^^^^^^

答案 3 :(得分:1)

以下是其他一些写这个的方法。你可能会发现它们更具表现力。

#include <vector>
#include <algorithm>
#include <numeric>

std::vector<double> create1(double i, double h)
{
  std::vector<double> v(10);
  std::generate(std::begin(v), std::end(v), 
                [&]() mutable
  {
    auto result = i;
    i += h;
    return i;
  });
  return v;
}

std::vector<double> create2(double i, double h)
{
  std::vector<double> v(10);
  for (std::size_t x = 0 ; v.size() ; ++x) {
    v[x] = i + h * x; 
  }
  return v;
}

std::vector<double> create3(double i, double h)
{
  struct emitter
  {
    emitter& operator++() {
      i += h;
    }
    operator double() const { return i; }
    double i, h;
  };
  std::vector<double> v(10);
  std::iota(v.begin(), v.end(), emitter { i, h });
  return v;
}

int main()
{
  auto v1 = create1(0, 0.1);
  auto v2 = create2(0, 0.1);
  auto v3 = create3(0, 0.1);
}

答案 4 :(得分:0)

无论它可能有什么其他问题,你的实现都有一个微妙的缺陷:它依赖于已经设置的向量中的每个先前值。

这不能保证有效,因为std::transform() does not guarantee in-order application of the operator