我将填充/初始化具有线性增加值的向量。例如,对于此向量中的每个元素,我希望下一个是a
比前一个更多。或者kth
元素的值为k*a
这样的事情:
float a = 1.132;
vector<float> v(100);
for (int n = 0; n < 100; ++n)
{
v[n] = n*a;
}
有更优雅的方式吗?谢谢。
一个matlab的例子是linspace(beginning value, end value, number of points)
linspace(1,5, 6)
ans =
1.0000 1.8000 2.6000 3.4000 4.2000 5.0000
你要做的第一件事是切换到使用std::generate
或std::generate_n
而不是for循环。 generate
版本看起来像
int main()
{
float a = 1.132;
std::vector<float> v(100);
std::generate(v.begin(), v.end(), [n = 0, &a]() mutable { return n++ * a; });
}
另一种选择是创建一个迭代器,它将在迭代时生成值。这样做的好处是,您不需要使用任何默认构造值初始化v
(这可能是/昂贵的)。然后使用向量范围构造函数,它将初始化所有元素。只要迭代器遵守前向迭代器要求,那么向量将找出所需的空间(如果不是随机访问导致完整迭代),则分配,然后初始化(完全迭代)。对于双重迭代,这可能是昂贵的,因此它可能不会更快,并且可能比生成情况慢(因为零初始化非常快)。
如果您可以访问C ++ 11,则可以将std::generate
与lambda一起使用:
std::generate(v.begin(), v.end(), [n = 0, &a] () mutable { return a * n++; });
但是,对于这个用例,如评论中所述,几乎不需要矢量。
你可以定义一个具有operator++
和转换为float
的类型,并使用std::iota
#include <algorithm>
#include <vector>
struct spacer
{
spacer(float scale, int count = 0) : scale(scale), count(count) {}
spacer operator++(){ ++count; return *this; }
operator float(){ return count * scale; }
private:
float scale;
int count;
};
int main()
{
std::vector<float> v(100);
std::iota(v.begin(), v.end(), spacer(1.132));
}
如果你有权访问boost
,你可以使用它和boost::counting_iterator
实例化你的向量
#include <algorithm>
#include <vector>
#include <tuple>
#include <boost/iterator/counting_iterator.hpp>
struct spacer
{
spacer(float scale, int count = 0) : scale(scale), count(count) {}
spacer operator++(){ ++count; return *this; }
operator float() const{ return count * scale; }
bool operator==(const spacer & rhs) const{ return std::tie(count, scale) == std::tie(rhs.count, rhs.scale); }
private:
float scale;
int count;
};
int main()
{
using iter = boost::counting_iterator<spacer, std::forward_iterator_tag, std::ptrdiff_t>;
std::vector<float> v(iter(spacer(1.132)), iter(spacer(1.132, 100)));
}
如果你正在寻找像matlab linspace这样的东西,它在C ++中不是直接可用的,但是编写一个函数很容易。喜欢:
std::vector<float> linspace(float start, float end, size_t points)
{
std::vector<float> res(points);
float step = (end - start) / (points - 1);
size_t i = 0;
for (auto& e : res)
{
e = start + step * i++;
}
return res;
}
然后你就可以使用它:
int main()
{
std::vector<float> v = linspace(1, 5, 6);
for (auto f : v) std::cout << f << " ";
std::cout << std::endl;
return 0;
}
输出:
1 1.8 2.6 3.4 4.2 5