Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to shuffle a std::vector?

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); } 
like image 880
laurent Avatar asked Aug 03 '11 12:08

laurent


People also ask

How do you shuffle a vector?

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.

How do you shuffle a set in C++?

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.

How does Random_shuffle work in C++?

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.


2 Answers

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()); 
like image 193
user703016 Avatar answered Oct 21 '22 15:10

user703016


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; } 
like image 35
Mehmet Fide Avatar answered Oct 21 '22 17:10

Mehmet Fide