简体   繁体   中英

How to shuffle an array so that all elements change their place

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).

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].

What about this?

  1. Allocate an array which contains numbers from 0 to arrayLength-1
  2. Shuffle the array
  3. If there is no element in array whose index equals its value, continue to step 4; otherwise repeat from step 2.
  4. Use shuffled array values as indexes for your array.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM