Saya mencari cara umum yang dapat digunakan kembali untuk mengacak a std::vector
di C ++. Beginilah cara saya saat ini melakukannya, tetapi menurut saya itu tidak terlalu efisien karena memerlukan array perantara dan perlu mengetahui jenis itemnya (DeckCard dalam contoh ini):
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()
, ada API RNG yang lebih baik yang tersedia (Boost.Random atau 0x<random>
).Jawaban:
Mulai C ++ 11 dan seterusnya, Anda harus memilih:
Live example on Coliru
Pastikan untuk menggunakan kembali contoh yang sama di
rng
seluruh beberapa panggilan kestd::shuffle
jika Anda berniat untuk menghasilkan permutasi yang berbeda setiap saat!Selain itu, jika Anda ingin program Anda membuat urutan pengacakan yang berbeda setiap kali dijalankan, Anda dapat memasukkan konstruktor mesin acak dengan keluaran
std::random_device
:Untuk C ++ 98 Anda dapat menggunakan:
sumber
std::random_shuffle
.std::random_shuffle
jika ini menjadi masalah.random_shuffle
. Perilaku ini normal dan disengaja.#include <algorithm>
http://www.cplusplus.com/reference/algorithm/shuffle/
sumber
std::random_device
?Selain apa yang dikatakan @Cicada, Anda mungkin harus melakukan seed terlebih dahulu,
Per @ FredLarson komentar:
Jadi YMMV.
sumber
random_shuffle()
adalah implementasi yang ditentukan, jadi mungkin tidak digunakanrand()
sama sekali. Maka tidaksrand()
akan berpengaruh. Saya pernah mengalami itu sebelumnya.random_shuffle
digunakan untuk menghasilkan bilangan acak adalah definisi implementasi. Ini berarti bahwa pada implementasi Anda ia menggunakanrand()
(dan karenanya srand () berfungsi) tetapi pada saya dapat menggunakan sesuatu yang sama sekali berbeda, yang berarti bahwa pada implementasi saya bahkan dengan srand setiap kali saya menjalankan program saya akan mendapatkan hasil yang sama.Jika Anda menggunakan boost, Anda bisa menggunakan kelas ini (
debug_mode
disetel kefalse
, jika Anda ingin pengacakan bisa diprediksi di antara eksekusi Anda harus menyetelnya ketrue
):Kemudian Anda dapat mengujinya dengan kode ini:
sumber
std::random_device
?Bahkan bisa lebih sederhana, penyemaian dapat dihindari sepenuhnya:
Ini akan menghasilkan pengocokan baru setiap kali program dijalankan. Saya juga menyukai pendekatan ini karena kesederhanaan kodenya.
Ini berfungsi karena yang kita butuhkan
std::shuffle
hanyalah aUniformRandomBitGenerator
, yang persyaratannyastd::random_device
memenuhi.Catatan: jika mengocok berulang kali, mungkin lebih baik menyimpannya
random_device
di variabel lokal:sumber
random_device
...random_device
dirancang untuk dipanggil hanya sekali untuk menyemai PRNG, tidak untuk dipanggil berulang kali (yang dapat menghabiskan entropi yang mendasarinya dengan cepat dan menyebabkannya beralih ke skema pembangkitan yang kurang optimal)Tergantung dari standar yang harus Anda ikuti (C ++ 11 / C ++ 14 / C ++ 17), halaman "cppreference" ini menyediakan contoh yang cukup bagus: https://en.cppreference.com/w/cpp/algorithm/ random_shuffle .
sumber