ALi*_*iff 4 c++ random algorithm c++20
如何在任何给定的整数范围内随机选取多个值?
对于std::sample(),
一种可能的实现是:
void Sample(
int first, int last, std::vector<int> *out, std::size_t n, std::mt19937 *g)
{
std::vector<int> in{};
for (int i = first; i < last; ++i)
{
in.emplace_back(i);
}
std::sample(in.begin(), in.end(), std::back_inserter(*out), n, *g);
}
Run Code Online (Sandbox Code Playgroud)
但我很犹豫,因为创建in向量似乎多余且不切实际,
特别是当first是 0 并且last是非常大的数字时。
是否有任何公共实现或库可以满足此要求?例如:
sample(int first, int last, ...)或者,ranges::sample(int n, ...)In C++20 you can sample on iota_view
#include <ranges>
#include <vector>
#include <algorithm>
#include <random>
void Sample(
int first, int last, std::vector<int> *out, std::size_t n, std::mt19937 *g)
{
std::ranges::sample(
std::views::iota(first, last), std::back_inserter(*out), n, *g);
}
Run Code Online (Sandbox Code Playgroud)
Note that the above does not work in libstdc++ because ranges::sample incorrectly uses the std::sample's implementation. Since iota_view's iterator only satisfies Cpp17InputIterator, std::sample requires that the output range must be a random access iterator, which is not the case for back_inserter_iterator.
The workaround is to pre-resize the vector.
void Sample(
int first, int last, std::vector<int> *out, std::size_t n, std::mt19937 *g)
{
out->resize(n);
std::ranges::sample(
std::views::iota(first, last), out->begin(), n, *g);
}
Run Code Online (Sandbox Code Playgroud)
which works in both libstdc++ and MSVC-STL.
| 归档时间: |
|
| 查看次数: |
1222 次 |
| 最近记录: |