用等距值填充 std::vector<double> 的最简单方法

Ale*_*ph0 4 c++ stl stdvector

假设我有价值观double startdouble end和步长double step

填充std::vector<double>从 at 开始startstepsize随着当前值小于递增的值的最简单方法是end什么?

我在问自己,是否有一个 stl 函数使这个任务成为单线任务。

std::vector<double> fill(double start, double end, double step) {
  // Code
}

main() {
  auto ret=fill(0.2, 2.3, 0.2);
  // ret = {0.2, 0.4, 0.6, ... , 2.2}
}
Run Code Online (Sandbox Code Playgroud)

Ric*_*ges 5

再次出于学术兴趣,并且可能将预期设计弯曲std::iota到突破点:

std::iota(x.begin(), x.end(), double_iota(step, min));
Run Code Online (Sandbox Code Playgroud)

使用以下 double_iota 定义:

struct double_iota
{
    double_iota(double inc, double init_value = 0.0) : _value(init_value), _inc(inc) {}

    operator double() const { return _value; }
    double_iota& operator++() { _value += _inc; return *this; }
    double _value;
    double _inc;
};
Run Code Online (Sandbox Code Playgroud)

测试程序:

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

struct double_iota
{
    double_iota(double inc, double init_value = 0.0) : _value(init_value), _inc(inc) {}

    operator double() const { return _value; }
    double_iota& operator++() { _value += _inc; return *this; }
    double _value;
    double _inc;
};

int main()
{
    double min = 1.0;
    double max = 2.3;
    double step = 0.2;

    std::vector<double> x(std::size_t(((max + step - std::numeric_limits<double>::epsilon()) - min) / step));
    std::iota(x.begin(), x.end(), double_iota(step, min));

    std::copy(x.begin(), x.end(), std::ostream_iterator<double>(std::cout, ", "));
}
Run Code Online (Sandbox Code Playgroud)

预期成绩:

1, 1.2, 1.4, 1.6, 1.8, 2, 2.2, 
Run Code Online (Sandbox Code Playgroud)

更新:

或者我们可以构建一个自定义迭代器,它允许我们在一行中真正表达序列:

    std::vector<double> x(double_inc_iterator(min, step), double_inc_iterator(max));
Run Code Online (Sandbox Code Playgroud)

如下:

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


struct double_inc_iterator : std::iterator<std::forward_iterator_tag, double>
{
    double_inc_iterator(double initial, double inc = 1.0) : _value(initial), _inc(inc) {}
    value_type operator*() const { return _value; }
    double_inc_iterator& operator++() { _value += _inc; return *this; }

    bool operator==(double_inc_iterator const& r) const { return _value >= r._value; }
    bool operator!=(double_inc_iterator const& r) const { return !(*this == r); }

    value_type _value;
    value_type _inc;
};

int main()
{
    double min = 1.0;
    double max = 2.3;
    double step = 0.2;

    std::vector<double> x(double_inc_iterator(min, step), double_inc_iterator(max));

    std::copy(x.begin(), x.end(), std::ostream_iterator<double>(std::cout, ", "));
}
Run Code Online (Sandbox Code Playgroud)

现在我们甚至不需要中间向量:

std::copy(double_inc_iterator(min, step),
          double_inc_iterator(max),
          std::ostream_iterator<double>(std::cout, ", "));
Run Code Online (Sandbox Code Playgroud)