Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using `transform` to create an increasing vector

Tags:

c++

std

c++11

I am trying to make an increasing vector using transform and must not be doing it correctly. I want to use transform. What am I doing wrong?

PS - I will be using the c++ 11 standard and 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;
}
like image 923
oliversm Avatar asked Jul 14 '26 07:07

oliversm


2 Answers

The conversion to unsigned int is truncating each value when it is used to calculate the next

like image 57
Caleth Avatar answered Jul 15 '26 19:07

Caleth


std::transform - Using an unary operator

std::transform applies the given function to a range and stores the result in another range, beginning at d_first.

Via std::transform and a closure you can initialize your 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 - Increment via a callable

Assigns each element in range [first, last) a value generated by the given function object

If you want a custom increment, you can use 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 - Increment via ++value

Slightly off topic. You can provide a type with a operator++ for an increment of 0.1 but it is not intuitive for the reader.

You can use std::iota which relies on operator++.

Fills the range [first, last) with sequentially increasing values, starting with value and repetitively evaluating ++value.

The code in your case will be:

#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
}

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!