Przejdź do głównej zawartości

std::shuffle() algorithm

// (1)
template< class RandomIt, class URBG >
void shuffle( RandomIt first, RandomIt last, URBG&& g );

Reorders the elements in the given range [first; last) such that each possible permutation of those elements has equal probability of appearance.

Parameters

first
last

The range of elements to shuffle.

g

A UniformRandomBitGenerator whose result type is convertible to std::iterator_traits<RandomIt>::difference_type.

Type requirements

RandomItLegacyRandomAccessIterator
ValueSwappable
std::remove_reference_t<URBG>UniformRandomBitGenerator

Return value

(none)

Complexity

Linear in std::distance(first, last);

Exceptions

(none)

Possible implementation

shuffle (1)
template<class RandomIt>
template<class RandomIt, class URBG>
void shuffle(RandomIt first, RandomIt last, URBG&& g)
{
using diff_t = typename std::iterator_traits<RandomIt>::difference_type;
using distr_t = std::uniform_int_distribution<diff_t>;
using param_t = typename distr_t::param_type;

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

Note that the implementation is not dictated by the standard, so even if you use exactly the same or URBG (Uniform Random Number Generator) you may get different results with different standard library implementations.

Main.cpp
#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
5 2 1 4 6 3 7 10 9 8
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::shuffle() algorithm

// (1)
template< class RandomIt, class URBG >
void shuffle( RandomIt first, RandomIt last, URBG&& g );

Reorders the elements in the given range [first; last) such that each possible permutation of those elements has equal probability of appearance.

Parameters

first
last

The range of elements to shuffle.

g

A UniformRandomBitGenerator whose result type is convertible to std::iterator_traits<RandomIt>::difference_type.

Type requirements

RandomItLegacyRandomAccessIterator
ValueSwappable
std::remove_reference_t<URBG>UniformRandomBitGenerator

Return value

(none)

Complexity

Linear in std::distance(first, last);

Exceptions

(none)

Possible implementation

shuffle (1)
template<class RandomIt>
template<class RandomIt, class URBG>
void shuffle(RandomIt first, RandomIt last, URBG&& g)
{
using diff_t = typename std::iterator_traits<RandomIt>::difference_type;
using distr_t = std::uniform_int_distribution<diff_t>;
using param_t = typename distr_t::param_type;

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

Note that the implementation is not dictated by the standard, so even if you use exactly the same or URBG (Uniform Random Number Generator) you may get different results with different standard library implementations.

Main.cpp
#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
5 2 1 4 6 3 7 10 9 8
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.