如何对数组进行混洗以使所有元素都改变它们的位置

Nic*_*ick 6 c++ random shuffle

我需要改组一个数组,以便所有数组元素都应该改变它们的位置.给定一个数组[0,1,2,3],可以得到[1,0,3,2][3,2,0,1]不得[3,1,2,0](因为2保持不变).我认为算法不是特定于语言的,但为了以防万一,我需要它在C++程序中(std::random_shuffle由于额外的要求我不能使用).

Moo*_*uck 5

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
Run Code Online (Sandbox Code Playgroud)

这可以保证每个值不在它开始的位置,但不保证每个值在重复时都会改变.

BeeOnRope指出,虽然简单,但这是有缺陷的.给定列表[0,1,2,3],该算法不能产生输出[1,0,3,2].

  • 这无法生成所有可能的 _derangements_。考虑列表 `[0,1,2,3]` 和上面第一个允许的输出:`[1,0,3,2]`。永远无法生成此输出!请注意,在最后一步(即将交换 3),列表看起来像 `[?,?,X,3]`,其中 `X` 不能是 2,因为它刚刚被交换到了前一步。所以在最后一步之后`X`以3结尾的唯一方法意味着列表看起来像`[?,?,3,X]`并且X不能是2,因此无法生成排列。该算法仅生成一小部分可能的紊乱。 (2认同)

Bor*_*ška 5

那这个呢?

  1. 分配一个包含从0到arrayLength-1的数字的数组
  2. 随机播放阵列
  3. 如果数组中没有索引等于其值的元素,则继续执行步骤4; 否则从第2步重复.
  4. 使用混洗数组值作为数组的索引.