Reputation: 3435
I need to shuffle an array so that all array elements should change their location.
Given an array [0,1,2,3]
it would be ok to get [1,0,3,2]
or [3,2,0,1]
but not [3,1,2,0]
(because 2
left unchanged).
I suppose algorithm would not be language-specific, but just in case, I need it in C++ program (and I cannot use std::random_shuffle
due to the additional requirement).
Upvotes: 8
Views: 4501
Reputation: 66922
For each element e
If there is an element to the left of e
Select a random element r to the left of e
swap r and e
This guarantees that each value isn't in the position that it started, but doesn't guarantee that each value changes if there's duplicates.
BeeOnRope notes that though simple, this is flawed. Given the list [0,1,2,3], this algorithm cannot produce the output [1,0,3,2].
Upvotes: 4
Reputation: 26184
It's not going to be very random, but you can rotate all the elements at least one position:
std::rotate(v.begin(), v.begin() + (rand() % v.size() - 1) + 1, v.end());
If v
was {1,2,3,4,5,6,7,8,9}
at the beginning, then after rotation it will be, for example: {2,3,4,5,6,7,8,9,1}
, or {3,4,5,6,7,8,9,1,2}
, etc.
All elements of the array will change position.
Upvotes: 2
Reputation: 1794
What about this?
Upvotes: 8
Reputation: 3595
I kind of have a idea in my mind hope it fits your application. Have one more container and this container will be a "map(int,vector(int))" . The key element will show index and the second element the vector will hold the already used values.
For example for the first element you will use rand function to find which element of the array you should use.Than you will check the map structure if this element of the array has been used for this index.
Upvotes: 1