使用步骤 c++ 构建向量
Posted
技术标签:
【中文标题】使用步骤 c++ 构建向量【英文标题】:Build a vector with step c++ 【发布时间】:2019-11-07 10:35:03 【问题描述】:是否可以在不使用 c++ 循环的情况下以固定的步长创建一个从一个值到另一个值的向量?
例如,我想构建一个从 1 到 10 的向量,步长为 0.5。在 MATLAB 中,我可以这样做:
vector = [1:0.5:10];
c++中有类似的东西吗?
【问题讨论】:
【参考方案1】:在std::generate_n
的帮助下,您可以
std::vector<double> v;
const int size = 10 * 2 - 1;
v.reserve(size);
std::generate_n(std::back_inserter(v), size, []() static double d = 0.5; return d += 0.5; );
LIVE
【讨论】:
【参考方案2】:你需要一个循环。 Matlab 只是对您隐藏循环。如果这是您经常做的事情,只需创建一个函数以使其更易于使用:
#include <vector>
auto make_vector(double beg, double step, double end)
std::vector<double> vec;
vec.reserve((end - beg) / step + 1);
while (beg <= end)
vec.push_back(beg);
beg += step;
return vec;
int main()
auto vec = make_vector(1, 0.5, 10);
【讨论】:
【参考方案3】:没有循环是不可能的,但您可以隐藏循环,例如使用std::generate
或std::generate_n
:
constexpr size_t SIZE = (10 - 1) * 2;
std::vector<double> data(SIZE);
double new_value = 1.0;
std::generate(begin(data), end(data) [&new_value]()
double current_value = new_value;
new_value += 0.5;
return current_value;
);
当然,要写的内容很多,显式循环可能会更好:
std::vector<double> data;
for (double i = 1.0; i <= 10; i += 0.5)
data.push_back(i);
如果步进是“一”(例如1
或1.0
),那么您可以改用std::iota
:
std::vector<double> data(10);
std::iota(begin(data), end(data), 1.0); // Initializes the vector with values from 1.0 to 10.0
【讨论】:
【参考方案4】:不,C++ 中没有这样的东西。您必须创建一个循环并填充您的向量,例如:
std::vector<double> v;
v.reserve(19);
for(size_t i = 2; i < 21; ++i)
v.push_back(i / 2.);
我在这里使用整数循环而不是增量为 0.5 的双循环,以确保我获得的元素数量并最大限度地减少数值舍入误差(0.5 很好,但不是 1/3)。
【讨论】:
【参考方案5】:使用Ranges-v3库的简单解决方案:
#include <range/v3/all.hpp>
auto make_vector(double min, double step, double max)
const auto size = static_cast<std::size_t>((max - min) / step);
return ranges::views::iota(std::size_t0, size + 1) |
ranges::views::transform([min, step](auto i) return min + step * i; ) |
ranges::to<std::vector>();
int main()
auto vec = make_vector(1, .5, 5);
for (auto x : vec)
std::cout << x << ' ';
// Output: 1 1.5 2 2.5 3 3.5 4 4.5 5
范围将是 C++20 的 part。
【讨论】:
【参考方案6】:如果您需要做很多这样的事情,您可以轻松编写自己的函数,该函数可以与任何容器一起使用(支持保留并可由std::generate
填充):
template <typename TContainer>
TContainer fill(typename TContainer::value_type start,
typename TContainer::value_type step,
typename TContainer::value_type end)
size_t size = static_cast<size_t>((end - start)/step + 1);
TContainer output(size);
std::generate(std::begin(output), std::end(output),
[&start, step]()
return std::exchange(start, start + step);
);
return output;
那么你可以如下使用它:
auto vec = fill<std::vector<int>>(0, 2, 10);
auto list = fill<std::list<float>>(1, 0.3, 5);
Live example
你会得到:
vec: 0, 2, 4, 6, 8, 10
list: 1, 1.3, 1.6, 1.9, 2.2, 2.5, 2.8, 3.1, 3.4, 3.7, 4, 4.3, 4.6, 4.9
【讨论】:
return std::exchange(start, start + step);
@Evg Noooice!修改了答案。以上是关于使用步骤 c++ 构建向量的主要内容,如果未能解决你的问题,请参考以下文章
(C++ STL _ CMake ) —— 利用CMake来构建STL的学习项目的步骤
(C++ STL _ CMake ) —— 利用CMake来构建STL的学习项目的步骤
(C++ STL _ CMake ) —— 利用CMake来构建STL的学习项目的步骤