std::random...td::shuffle(3)
β¨ NAME β¨
std::random_shuffle,std::shuffle β std::random_shuffle,std::shuffle.
okay so this is the std::random_shuffle / std::shuffle page from the C++ Standard Libary manual (yes, βLibaryβ is literally how the manual name is spelled up there, and we respect the typo π). Itβs giving βtwo shuffle-ish functions, one of them kinda problematic, and a whole lot of template energy.β
πΈ Synopsis πΈ
Defined in header <algorithm>.
- Overload (1) β
(deprecated in C++14),(removed in C++17):
template< class RandomIt >
void random_shuffle( RandomIt first, RandomIt last );
- Overload (2),
RandomFunc&version β(until C++11):
template< class RandomIt, class RandomFunc >
void random_shuffle( RandomIt first, RandomIt last, RandomFunc& r );
- Overload (2),
RandomFunc&&version β(since C++11),(deprecated in C++14),(removed in C++17):
template< class RandomIt, class RandomFunc >
void random_shuffle( RandomIt first, RandomIt last, RandomFunc&& r );
- Overload (3) β
(since C++11):
template< class RandomIt, class URBG >
void shuffle( RandomIt first, RandomIt last, URBG&& g );
So what does it do? It reorders the elements in the range [first, last) so that every possible permutation of those elements has an equal probability of appearing. literally the βmake it random but fairβ vibe check π
.
- The source of randomness is implementation-defined, but the function
std::randis often used. - The source of randomness is the function object
r. If any of these conditions is satisfied, the behavior is undefined:- The return type of
ris not convertible tostd::iterator_traits<RandomIt>::difference_type. - Given a positive value
nof typestd::iterator_traits<RandomIt>::difference_type, the result ofr(n)is not a randomly chosen value in the interval[0, n).
- The return type of
- The source of randomness is the object
g. Given the typeTasstd::remove_reference_t<URBG>, if any of these conditions is satisfied, the behavior is undefined:Tis not aUniformRandomBitGenerator.T::result_typeis not convertible tostd::iterator_traits<RandomIt>::difference_type(until C++20).
Also, if the type of*firstis notSwappable(until C++11), orRandomItis notValueSwappable(since C++11), the behavior is undefined. no cap, thatβs a whole yikes π.
π«Ά Parameters π«Ά
first, lastβ the range of elements to shuffle randomly.rβ function object returning a randomly chosen value.gβ generator object returning a randomly chosen value.
π¦ Type requirements π¦
RandomItmust meet the requirements ofLegacyRandomAccessIterator.
β Complexity β
Exactly std::distance(first, last) - 1 swaps.
π Possible implementation π
See also the implementations in libstdc++ and libc++.
random_shuffle (1)
template<class RandomIt>
void random_shuffle(RandomIt first, RandomIt last)
{
typedef typename std::iterator_traits<RandomIt>::difference_type diff_t;
for (diff_t i = last - first - 1; i > 0; --i)
{
using std::swap;
swap(first[i], first[std::rand() % (i + 1)]);
// rand() % (i + 1) is not actually correct, because the generated number is
// not uniformly distributed for most values of i. The correct code would be
// a variation of the C++11 std::uniform_int_distribution implementation.
}
}
random_shuffle (2)
template<class RandomIt, class RandomFunc>
void random_shuffle(RandomIt first, RandomIt last, RandomFunc&& r)
{
typedef typename std::iterator_traits<RandomIt>::difference_type diff_t;
for (diff_t i = last - first - 1; i > 0; --i)
{
using std::swap;
swap(first[i], first[r(i + 1)]);
}
}
shuffle (3)
template<class RandomIt, class URBG>
void shuffle(RandomIt first, RandomIt last, URBG&& g)
{
typedef typename std::iterator_traits<RandomIt>::difference_type diff_t;
typedef std::uniform_int_distribution<diff_t> distr_t;
typedef typename distr_t::param_type param_t;
distr_t D;
for (diff_t i = last - first - 1; i > 0; --i)
{
using std::swap;
swap(first[i], first[D(g, param_t(0, i))]);
}
}
π Notes π
Bestie, the implementation is not dictated by the standard, so even if you use exactly the same RandomFunc or URBG (Uniform Random Number Generator), you may get different results with different standard library implementations. itβs giving βsame input, different auraβ π.
The reason for removing std::random_shuffle in C++17 is that the iterator-only version usually depends on std::rand, which is now also discussed for deprecation. (std::rand should be replaced with the classes of the <random> header, as std::rand is considered harmful.) In addition, the iterator-only std::random_shuffle version usually depends on a global state. The std::shuffleβs shuffle algorithm is the preferred replacement, as it uses a URBG as its 3rd parameter. periodt π
.
π Example π
Randomly shuffles the sequence [1, 10] of integers:
// Run this code
#include <algorithm>
#include <iostream>
#include <iterator>
#include <random>
#include <vector>
int main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(v.begin(), v.end(), g);
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}
Possible output:
8 6 10 4 2 3 7 1 9 5
π Defect reports π
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
- LWG 395 β Applied to C++98 β Behavior as published: the source of randomness of overload (1) was not specified, and
std::randcould not be the source due to the C library requirement β Correct behavior: it is implementation-defined, and usingstd::randis allowed. - LWG 552 (N2423) β Applied to C++98 β Behavior as published:
rwas not required to be the source of randomness of overload (2)^[1] β Correct behavior: required.
^[1] Overload (3) has the same defect, but that part of the resolution is not applicable to C++98.
π See also π
next_permutationβ generates the next greater lexicographic permutation of a range of elements (function template).prev_permutationβ generates the next smaller lexicographic permutation of a range of elements (function template).ranges::shuffle(C++20)β randomly re-orders elements in a range (niebloid).
okay thatβs the whole page, bestie π shoutout to the source/version http://cppreference.com and the date 2024.06.10 β slay, bye π¦
π¦ 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