Я ищу универсальный способ многоразового перетасовки std::vector
в C ++. Вот как я сейчас это делаю, но я думаю, что это не очень эффективно, потому что ему нужен промежуточный массив, и он должен знать тип элемента (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()
, есть более подходящие API-интерфейсы RNG (Boost.Random или 0x<random>
).Ответы:
Начиная с C ++ 11, вы должны предпочесть:
Live example on Coliru
Не забудьте повторно использовать один и тот же экземпляр в
rng
нескольких вызовах,std::shuffle
если вы собираетесь каждый раз генерировать разные перестановки!Более того, если вы хотите, чтобы ваша программа создавала разные последовательности перемешивания каждый раз при запуске, вы можете заполнить конструктор случайного механизма выводом
std::random_device
:Для C ++ 98 вы можете использовать:
источник
std::random_shuffle
.std::random_shuffle
если это проблема.random_shuffle
. Это нормальное и преднамеренное поведение.#include <algorithm>
http://www.cplusplus.com/reference/algorithm/shuffle/
источник
std::random_device
?В дополнение к тому, что сказал @Cicada, вам, вероятно, следует сначала посеять,
Комментарий @FredLarson:
Итак, YMMV.
источник
random_shuffle()
определяется реализацией, поэтому она может вообще не использоватьсяrand()
. Тогда неsrand()
будет никакого эффекта. Я уже сталкивался с этим раньше.random_shuffle
используется для генерации случайного числа, определяется реализацией. Это означает, что в вашей реализации он используетrand()
(и, следовательно, srand () работает), но в моей он может использовать что-то совершенно другое, а это означает, что в моей реализации даже с srand каждый раз, когда я запускаю программу, я получаю те же результаты.Если вы используете boost, вы можете использовать этот класс (
debug_mode
установлен вfalse
, если вы хотите, чтобы рандомизация могла быть предсказуемой между выполнением, вы должны установить егоtrue
):Затем вы можете проверить это с помощью этого кода:
источник
std::random_device
?Это может быть еще проще, можно полностью избежать посева:
Это приведет к новому перемешиванию при каждом запуске программы. Мне также нравится такой подход из-за простоты кода.
Это работает, потому что все, что нам нужно,
std::shuffle
это aUniformRandomBitGenerator
, чьи требованияstd::random_device
соответствуют.Примечание: при многократном перемешивании может быть лучше сохранить
random_device
в локальной переменной:источник
random_device
...random_device
предназначен для вызова только один раз для заполнения ГПСЧ, а не для повторного вызова (что может быстро исчерпать базовую энтропию и привести к переключению на неоптимальную схему генерации)В зависимости от стандарта, которому вы должны следовать (C ++ 11 / C ++ 14 / C ++ 17), эта страница cppreference предоставляет довольно хорошие примеры: https://en.cppreference.com/w/cpp/algorithm/ random_shuffle .
источник