范围函数类似于 python 但对于 C++ 17 (double)
range function like python but for C++ 17 (double)
我正在尝试创建一个函数,通过特定步骤从头到尾用值填充我的向量。对于类型 double 和 C++ 17 版本。知道怎么做吗?
vector<double> generateRange(double start, double end, double step)
{
}
int main()
{
// return [10, 10.5, 11,...., 12]
auto range = generateRange(10, 12, 0.5);
for (auto i : range)
std::cout << i << ' ';
}
对于 int 这将是一个非常简单的循环,但是对于 double...
我认为您绝对不需要在迭代之前将值存储在向量中。
我会做这样的事情
/**
g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
-pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
-g -O0 -UNDEBUG -fsanitize=address,undefined
**/
#include <iostream>
#include <algorithm>
inline
auto // iterable
generate_range(double from_count,
double to_count,
double step)
{
struct Iter
{
double count;
double step;
bool operator!=(const double &rhs) const { return count<=rhs; } // oh!!!
void operator++() { count+=step; }
auto operator*() const { return count; }
};
struct Enumerate
{
double from_count;
double to_count;
double step;
auto begin() { return Iter{from_count, step}; }
auto end() { return to_count; }
};
return Enumerate{std::min(from_count, to_count),
std::max(from_count, to_count),
step};
}
int
main()
{
for(const auto &value: generate_range(10, 12, 0.5))
{
std::cout << value << ' ';
}
std::cout << '\n'; // 10 10.5 11 11.5 12
for(const auto &value: generate_range(239.99, 237.36, 1))
{
std::cout << value << ' ';
}
std::cout << '\n'; // 237.36 238.36 239.36
return 0;
}
注意 !=
实际上测试 <=
;它很丑,但它有效。
此函数 returns 提供 begin()
和 end()
成员函数,以便 range-for 循环可以使用它。
编辑:为反转边界添加了min/max。
例如,您可以编写一个简单的循环来生成您想要的向量。
然而,python 中的 range
函数不是 return 列表而是生成器,后者速度要快得多。您还应该 return 使用 C++ 生成器(范围),而不是 return 使用向量。生成器的实现要高级一些。
标准库附带可用于构建此类生成器的工具。这是您的示例:
auto step_fun = [=](auto x) { return x * step + start; };
auto end_pred = [=](auto x) { return x <= end; };
auto range =
std::views::iota(0)
| std::views::transform(step_fun)
| std::views::take_while(end_pred);
我的问题解决方案:
#include <vector>
using std::vector;
#include <iostream>
using std::cout;
#include <algorithm>
vector<double> generateRange(double start, double end, double step)
{
int vector_size = (end - start) / step;
vector<double> values(vector_size);
std::for_each(begin(values), std::end(values),
[start, step, i = 0](double &actual) mutable {
actual = start + step * i;
i++;
});
return values;
}
int main()
{
// return [10, 10.5, 11,...., 12]
auto range = generateRange(10, 12, 0.5);
for (auto i : range)
std::cout << i << ' ';
}
如果您对我使用的函数有任何疑问,请随时提问:)
我正在尝试创建一个函数,通过特定步骤从头到尾用值填充我的向量。对于类型 double 和 C++ 17 版本。知道怎么做吗?
vector<double> generateRange(double start, double end, double step)
{
}
int main()
{
// return [10, 10.5, 11,...., 12]
auto range = generateRange(10, 12, 0.5);
for (auto i : range)
std::cout << i << ' ';
}
对于 int 这将是一个非常简单的循环,但是对于 double...
我认为您绝对不需要在迭代之前将值存储在向量中。
我会做这样的事情
/**
g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
-pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
-g -O0 -UNDEBUG -fsanitize=address,undefined
**/
#include <iostream>
#include <algorithm>
inline
auto // iterable
generate_range(double from_count,
double to_count,
double step)
{
struct Iter
{
double count;
double step;
bool operator!=(const double &rhs) const { return count<=rhs; } // oh!!!
void operator++() { count+=step; }
auto operator*() const { return count; }
};
struct Enumerate
{
double from_count;
double to_count;
double step;
auto begin() { return Iter{from_count, step}; }
auto end() { return to_count; }
};
return Enumerate{std::min(from_count, to_count),
std::max(from_count, to_count),
step};
}
int
main()
{
for(const auto &value: generate_range(10, 12, 0.5))
{
std::cout << value << ' ';
}
std::cout << '\n'; // 10 10.5 11 11.5 12
for(const auto &value: generate_range(239.99, 237.36, 1))
{
std::cout << value << ' ';
}
std::cout << '\n'; // 237.36 238.36 239.36
return 0;
}
注意 !=
实际上测试 <=
;它很丑,但它有效。
此函数 returns 提供 begin()
和 end()
成员函数,以便 range-for 循环可以使用它。
编辑:为反转边界添加了min/max。
例如,您可以编写一个简单的循环来生成您想要的向量。
然而,python 中的 range
函数不是 return 列表而是生成器,后者速度要快得多。您还应该 return 使用 C++ 生成器(范围),而不是 return 使用向量。生成器的实现要高级一些。
标准库附带可用于构建此类生成器的工具。这是您的示例:
auto step_fun = [=](auto x) { return x * step + start; };
auto end_pred = [=](auto x) { return x <= end; };
auto range =
std::views::iota(0)
| std::views::transform(step_fun)
| std::views::take_while(end_pred);
我的问题解决方案:
#include <vector>
using std::vector;
#include <iostream>
using std::cout;
#include <algorithm>
vector<double> generateRange(double start, double end, double step)
{
int vector_size = (end - start) / step;
vector<double> values(vector_size);
std::for_each(begin(values), std::end(values),
[start, step, i = 0](double &actual) mutable {
actual = start + step * i;
i++;
});
return values;
}
int main()
{
// return [10, 10.5, 11,...., 12]
auto range = generateRange(10, 12, 0.5);
for (auto i : range)
std::cout << i << ' ';
}
如果您对我使用的函数有任何疑问,请随时提问:)