how to shuffle a list?

I'm sure that I can shuffle a vector with shuffle function.
But I dont know how to shuffle a list?

case 1:
#include<iostream>
#include<vector>
#include<cstdlib>
#include<algorithm>
#include<random>
#include<list>
using namespace std;

int main()
{
std::random_device rd;
std::mt19937 gen(rd());
list<int> lat;
for (int i = 0;i < 10;i++)
lat.push_front(i);
for (list<int>::iterator it = lat.begin();it != lat.end();it++)
{
cout << *it << " ";
}
cout << "\n";
shuffle(lat.begin(), lat.end(), gen);

for (list<int>::iterator it = lat.begin();it != lat.end();it++)
{
cout << *it << " ";
}
cout << "\n";
return 0;
}
The code above is wrong!How to fix it?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template < typename T > void shuffle( std::list<T>& lst ) // shuffle contents of a list
{
    // create a vector of (wrapped) references to elements in the list
    // http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper
    std::vector< std::reference_wrapper< const T > > vec( lst.begin(), lst.end() ) ;

    // shuffle (the references in) the vector
    std::shuffle( vec.begin(), vec.end(), std::mt19937{ std::random_device{}() } ) ;

    // copy the shuffled sequence into a new list
    std::list<T> shuffled_list {  vec.begin(), vec.end() } ;

    // swap the old list with the shuffled list
    lst.swap(shuffled_list) ;
}

http://coliru.stacked-crooked.com/a/312e4e0426737de2
http://rextester.com/HHTW39678

Note: This would be more efficient if copying the value_type of the list is expensive, but it is movable.
If move semantics is uncharted waters for you, ignore this for now.
1
2
3
    // copy the shuffle sequence into a new list
    std::list<T> shuffled_list ; // { vec.begin(), vec.end() } ;
    for( auto& ref : vec ) shuffled_list.push_back( std::move( ref.get() ) ) ;
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<iostream>
#include<algorithm>
#include<random>
#include<list>
#include<vector>
#include<chrono>
using namespace std;
 
mt19937 gen( chrono::system_clock::now().time_since_epoch().count() );

//============================

template <class T > void listShow( list<T> &L )
{
   for ( auto &e : L ) cout << e << " ";
   cout << endl;
}

//============================

template <class T > void listShuffle( list<T> &L )
{
   vector<T> V( L.begin(), L.end() );
   shuffle( V.begin(), V.end(), gen );
   L.assign( V.begin(), V.end() );
}

//============================

int main()
{
   list<int> lat;
   for ( int i = 0; i < 10; i++ ) lat.push_front(i);
   listShow( lat );
  
   listShuffle( lat );
   listShow( lat );
}
Last edited on
Topic archived. No new replies allowed.