std::ranges::shuffle(3)
π std::ranges::shuffle(3) π
okay bestie, this one is from the C++ Standard Libary manual (yes, that spelling is right there on the page, iykyk) and itβs literally the βmake my range go chaotic goodβ algorithm. β¨
πΈ NAME πΈ
std::ranges::shuffle β std::ranges::shuffle. Thatβs the name, and itβs serving exactly that. π
π¦ Synopsis π¦
Defined in header <algorithm>.
π« Call signature π«
Overload (1) is since C++20, and itβs giving very βiterator pair + generatorβ energy:
template< std::random_access_iterator I, std::sentinel_for<I> S, class Gen >
requires std::permutable<I> &&
std::uniform_random_bit_generator<std::remove_reference_t<Gen>>
I shuffle( I first, S last, Gen&& gen );
Overload (2) is also since C++20, and itβs the range-y twin:
template< ranges::random_access_range R, class Gen >
requires std::permutable<ranges::iterator_t<R>> &&
std::uniform_random_bit_generator<std::remove_reference_t<Gen>>
ranges::borrowed_iterator_t<R> shuffle( R&& r, Gen&& gen );
So like, overload (1) reorders the elements in the given range [first, last) so that each possible permutation of those elements has equal probability of appearance. Equal probability, no cap. π²
Overload (2) is the same as (1), but it uses r as the range, as if using ranges::begin(r) as first and ranges::end(r) as last. Bestie behavior. π«Ά
The function-like entities described on this page are niebloids, that is:
- Explicit template argument lists cannot be specified when calling any of them.
- None of them are visible to argument-dependent lookup.
- When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.
In practice, they may be implemented as function objects, or with special compiler extensions.
πΌ Parameters πΌ
first,lastβ the range of elements to shuffle randomlyrβ the range of elements to shuffle randomlygenβ the random number generator
β¨ Return value β¨
An iterator equal to last. Thatβs it. Thatβs the return value. π
π₯ Complexity π₯
Exactly (last - first) - 1 swaps. Not more, not less, periodt. π
π§ Possible implementation π§
struct shuffle_fn
{
template<std::random_access_iterator I, std::sentinel_for<I> S, class Gen>
requires std::permutable<I> &&
std::uniform_random_bit_generator<std::remove_reference_t<Gen>>
I operator()(I first, S last, Gen&& gen) const
{
using diff_t = std::iter_difference_t<I>;
using distr_t = std::uniform_int_distribution<diff_t>;
using param_t = typename distr_t::param_type;
distr_t D;
const auto n {last - first};
for (diff_t i {1}; i < n; ++i)
ranges::iter_swap(first + i, first + D(gen, param_t(0, i)));
return ranges::next(first, last);
}
template<ranges::random_access_range R, class Gen>
requires std::permutable<ranges::iterator_t<R>> &&
std::uniform_random_bit_generator<std::remove_reference_t<Gen>>
ranges::borrowed_iterator_t<R> operator()(R&& r, Gen&& gen) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::forward<Gen>(gen));
}
};
inline constexpr shuffle_fn shuffle {};
π Example π
// Run this code
#include <algorithm>
#include <array>
#include <iostream>
#include <random>
void print(const auto& a)
{
for (const auto e : a)
std::cout << e << ' ';
std::cout << '\n';
}
int main()
{
std::array a {'A', 'B', 'C', 'D', 'E', 'F'};
print(a);
std::random_device rd;
std::mt19937 gen {rd()};
for (int i {}; i != 3; ++i)
{
std::ranges::shuffle(a, gen);
print(a);
}
}
Possible output:
A B C D E F
F E A C D B
E C B F A D
B A E C F D
π See also π
ranges::next_permutationβ generates the next greater lexicographic permutation of a range of elements(C++20)(niebloid)ranges::prev_permutationβ generates the next smaller lexicographic permutation of a range of elements(C++20)(niebloid)random_shuffleβ randomly re-orders elements in a range(until C++17)(function template)shuffleβ randomly re-orders elements in a range(C++11)(function template)
okay thatβs the whole page, bestie π«Ά. Cute sign-off time: source is http://cppreference.com, version/date is 2024.06.10, and the page is std::ranges::shuffle(3). Mwah πβ¨
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms