Namespaces
Variants

std:: random_shuffle, std:: shuffle

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
random_shuffle shuffle
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Défini dans l'en-tête <algorithm>
template < class RandomIt >
void random_shuffle ( RandomIt first, RandomIt last ) ;
(1) (déprécié en C++14)
(supprimé en C++17)
(2)
template < class RandomIt, class RandomFunc >
void random_shuffle ( RandomIt first, RandomIt last, RandomFunc & r ) ;
(jusqu'à C++11)
template < class RandomIt, class RandomFunc >
void random_shuffle ( RandomIt first, RandomIt last, RandomFunc && r ) ;
(depuis C++11)
(déprécié en C++14)
(supprimé en C++17)
template < class RandomIt, class URBG >
void shuffle ( RandomIt first, RandomIt last, URBG && g ) ;
(3) (depuis C++11)

Réorganise les éléments dans la plage donnée [ first , last ) de telle sorte que chaque permutation possible de ces éléments ait une probabilité égale d'apparition.

1) La source de l'aléatoire est définie par l'implémentation, mais la fonction std::rand est souvent utilisée.
2) La source d'aléatoire est l'objet fonction r .
Si l'une des conditions suivantes est satisfaite, le comportement est indéfini :
  • Le type de retour de r n'est pas convertible en std:: iterator_traits < RandomIt > :: difference_type .
  • Étant donné une valeur positive n de type std:: iterator_traits < RandomIt > :: difference_type , le résultat de r ( n ) n'est pas une valeur choisie aléatoirement dans l'intervalle [ 0 , n ) .
3) La source d'aléatoire est l'objet g .
Étant donné le type T comme std:: remove_reference_t < URBG > , si l'une des conditions suivantes est satisfaite, le comportement est indéfini :
(jusqu'à C++20)

Si le type de * first n'est pas Swappable (jusqu'à C++11) RandomIt n'est pas ValueSwappable (depuis C++11) , le comportement est indéfini.

Table des matières

Paramètres

first, last - la paire d'itérateurs définissant la plage d'éléments à mélanger aléatoirement
r - objet fonction retournant une valeur choisie aléatoirement
g - objet générateur retournant une valeur choisie aléatoirement
Exigences de type
-
RandomIt doit satisfaire aux exigences de LegacyRandomAccessIterator .

Complexité

Exactement std:: distance ( first, last ) - 1 échanges.

Implémentation possible

Voir également les implémentations dans libstdc++ et 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) n'est pas réellement correct, car le nombre généré n'est
        // pas uniformément distribué pour la plupart des valeurs de i. Le code correct serait
        // une variation de l'implémentation de std::uniform_int_distribution de C++11.
    }
}
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

Notez que l'implémentation n'est pas dictée par la norme, donc même si vous utilisez exactement la même RandomFunc ou URBG (Uniform Random Number Generator) vous pourriez obtenir des résultats différents avec différentes implémentations de la bibliothèque standard.

La raison de la suppression de std::random_shuffle en C++17 est que la version ne prenant que des itérateurs dépend généralement de std::rand , qui est maintenant également envisagée pour la dépréciation. ( std::rand devrait être remplacée par les classes de l'en-tête <random> , car std::rand est considérée comme nuisible .) De plus, la version de std::random_shuffle ne prenant que des itérateurs dépend généralement d'un état global. L'algorithme de mélange de std::shuffle est le remplacement privilégié, car il utilise un URBG comme troisième paramètre.

Exemple

Mélange aléatoirement la séquence [ 1 , 10 ] d'entiers :

#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';
}

Sortie possible :

8 6 10 4 2 3 7 1 9 5

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Applicable à Comportement publié Comportement corrigé
LWG 395 C++98 la source d'aléatoire de la surcharge (1) n'était pas spécifiée, et
std::rand ne pouvait pas être la source en raison de l'exigence de la bibliothèque C
elle est définie par l'implémentation,
et l'utilisation de std::rand est autorisée
LWG 552
( N2423 )
C++98 r n'était pas requis comme source
d'aléatoire de la surcharge (2) [1]
requis
  1. La surcharge (3) présente le même défaut, mais cette partie de la résolution n'est pas applicable à C++98.

Voir aussi

génère la prochaine permutation lexicographique supérieure d'une plage d'éléments
(modèle de fonction)
génère la prochaine permutation lexicographique inférieure d'une plage d'éléments
(modèle de fonction)
réorganise aléatoirement les éléments dans une plage
(objet fonction algorithme)