std::shuffle în C++

Amestecă aleatoriu elementele unui interval folosind un generator de numere aleatorii.

Sintaxă
void shuffle(RandomIt first, RandomIt last, URBG&& generator);

Ce face std::shuffle

std::shuffle rearanjează elementele într-o ordine aleatorie, fiecare permutare având aceeași șansă. Primește un generator, de obicei std::mt19937 inițializat cu std::random_device.

Cu un seed fix, același program dă aceeași ordine la fiecare rulare, ceea ce ajută la teste. Atenție: modul în care shuffle folosește numerele generatorului nu este fixat de standard, deci cu același seed GCC, Clang și MSVC pot da ordini diferite.

Vechiul std::random_shuffle a fost eliminat în C++17.

Parametri

Parametru Descriere
first, last Intervalul amestecat.
generator Un generator uniform de numere aleatorii, de exemplu std::mt19937.

Ce returnează

Nimic.

Exemple

Exemplul 1: Ordine diferită la fiecare rulare

#include <algorithm>
#include <numeric>
#include <print>
#include <random>
#include <vector>

int main() {
    std::vector<int> carti(10);
    std::iota(carti.begin(), carti.end(), 1);

    std::random_device rd;
    std::mt19937 gen(rd());
    std::shuffle(carti.begin(), carti.end(), gen);

    for (int c : carti) {
        std::print("{} ", c);
    }
    std::println("");
}

Rezultat posibil (diferă la fiecare rulare)

8 3 10 1 6 9 2 5 7 4

Exemplul 2: Seed fix: aceeași ordine la fiecare rulare

Rezultatul de mai jos este cel dat de libc++ (Clang); alt compilator poate da altă ordine pentru același seed.

#include <algorithm>
#include <print>
#include <random>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> intrebari{"Q1", "Q2", "Q3", "Q4", "Q5"};

    std::mt19937 gen(2026);
    std::ranges::shuffle(intrebari, gen);
    std::println("{}", intrebari);
}

Rezultat

["Q2", "Q4", "Q5", "Q1", "Q3"]

Greșeli frecvente

  • Creezi un std::mt19937 nou, cu seed fix, în interiorul unei funcții apelate de mai multe ori. Obții aceeași „amestecare” de fiecare dată.
  • Folosești std::random_shuffle din cod vechi: nu mai există în C++17.

Comenzi înrudite

  • std::mt19937: Generatorul Mersenne Twister: numere pseudo-aleatorii rapide și de calitate, reproductibile cu un seed fix.
  • std::random_device: Sursă de numere aleatorii nedeterministe, oferită de sistem; folosită de obicei ca seed pentru std::mt19937.
  • std::sample: Alege aleatoriu n elemente distincte dintr-un interval și le copiază la destinație.
  • std::rotate: Rotește elementele astfel încât middle devine primul element, iar cele dinaintea lui trec la final.