I am looking for a generic, reusable way to shuffle a std::vector
in C++. This is how I currently do it, but I think it's not very efficient because it needs an intermediate array and it needs to know the item type (DeckCard in this example):
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); }
How to shuffle a std::vector in C++ A vector shuffle can be done in the Fisher-Yates shuffle algorithm. In this algorithm, a linear scan of a vector is done and then swap each element with a random element among all the remaining element, including the element itself.
You can use std::shuffle to randomize the order of elements of pretty much any ordered structure. You can use this on an std::string , which would rearrange the individual characters.
std::random_shuffleRearranges the elements in the range [first,last) randomly. The function swaps the value of each element with that of some other randomly picked element. When provided, the function gen determines which element is picked in every case.
From C++11 onwards, you should prefer:
#include <algorithm> #include <random> auto rng = std::default_random_engine {}; std::shuffle(std::begin(cards_), std::end(cards_), rng);
Live example on Coliru
Make sure to reuse the same instance of rng
throughout multiple calls to std::shuffle
if you intend to generate different permutations every time!
Moreover, if you want your program to create different sequences of shuffles each time it is run, you can seed the constructor of the random engine with the output of std::random_device
:
auto rd = std::random_device {}; auto rng = std::default_random_engine { rd() }; std::shuffle(std::begin(cards_), std::end(cards_), rng);
For C++98 you may use:
#include <algorithm> std::random_shuffle(cards_.begin(), cards_.end());
http://www.cplusplus.com/reference/algorithm/shuffle/
// shuffle algorithm example #include <iostream> // std::cout #include <algorithm> // std::shuffle #include <vector> // std::vector #include <random> // std::default_random_engine #include <chrono> // std::chrono::system_clock int main () { // obtain a time-based seed: unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); std::default_random_engine e(seed); while(true) { std::vector<int> foo{1,2,3,4,5}; std::shuffle(foo.begin(), foo.end(), e); std::cout << "shuffled elements:"; for (int& x: foo) std::cout << ' ' << x; std::cout << '\n'; } return 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With