Szukam ogólnego, wielokrotnego użytku sposobu na przetasowanie std::vector
w C ++. Tak to teraz robię, ale myślę, że nie jest to zbyt wydajne, ponieważ wymaga tablicy pośredniej i musi znać typ elementu (w tym przykładzie DeckCard):
srand(time(NULL));
cards_.clear();
while (temp.size() > 0) {
int idx = rand() % temp.size();
DeckCard* card = temp[idx];
cards_.push_back(card);
temp.erase(temp.begin() + idx);
}
rand()
, dostępne są lepsze API RNG (Boost.Random lub 0x<random>
).Odpowiedzi:
Począwszy od C ++ 11, powinieneś preferować:
Live example on Coliru
Jeśli zamierzasz za każdym razem generować różne permutacje, pamiętaj o ponownym użyciu tego samego wystąpienia
rng
podczas wielu wywołań programustd::shuffle
!Ponadto, jeśli chcesz, aby Twój program tworzył różne sekwencje tasowań za każdym razem, gdy jest uruchamiany, możesz zaszczepić konstruktor silnika losowego z wynikiem
std::random_device
:W przypadku C ++ 98 możesz użyć:
źródło
std::random_shuffle
.std::random_shuffle
jeśli stanowi to problem.random_shuffle
. To zachowanie jest normalne i zamierzone.#include <algorithm>
http://www.cplusplus.com/reference/algorithm/shuffle/
źródło
std::random_device
?Oprócz tego, co powiedział @Cicada, prawdopodobnie powinieneś najpierw wysiać,
Komentarz Per @ FredLarson:
Więc YMMV.
źródło
random_shuffle()
jest zdefiniowana implementacja, więc możerand()
w ogóle nie używać . Wtedysrand()
nie miałoby to żadnego skutku. Spotkałem się z tym wcześniej.random_shuffle
służy do generowania liczby losowej, jest zdefiniowane jako implementacja. Oznacza to, że w twojej implementacji używarand()
(i dlatego srand () działa), ale na mojej może używać czegoś zupełnie innego, co oznacza, że na mojej implementacji nawet z srand za każdym razem, gdy uruchomię program, uzyskam te same wyniki.Jeśli używasz doładowania, możesz użyć tej klasy (
debug_mode
jest ustawiona nafalse
, jeśli chcesz, aby randomizacja była przewidywalna między wykonaniem, musisz ją ustawićtrue
):Możesz to przetestować tym kodem:
źródło
std::random_device
?Może być jeszcze prostsze, można całkowicie uniknąć wysiewu:
Spowoduje to utworzenie nowego tasowania przy każdym uruchomieniu programu. Podoba mi się również to podejście ze względu na prostotę kodu.
To działa, ponieważ wszystko, czego potrzebujemy,
std::shuffle
to aUniformRandomBitGenerator
, którego wymaganiastd::random_device
spełniają.Uwaga: w przypadku wielokrotnego tasowania może być lepiej przechowywać
random_device
w zmiennej lokalnej:źródło
random_device
random_device
jest zaprojektowany tak, aby był wywoływany tylko raz w celu zaszczepienia PRNG, nie może być wywoływany w kółko (co może szybko wyczerpać podstawową entropię i spowodować przejście do schematu generowania suboptymalnego)W zależności od standardu, którego musisz przestrzegać (C ++ 11 / C ++ 14 / C ++ 17) ta strona „cppreference” zawiera całkiem dobre przykłady: https://en.cppreference.com/w/cpp/algorithm/ random_shuffle .
źródło