如何洗牌一个数组,使所有元素改变它们的位置

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

本文关键字:元素 改变 位置 何洗牌 数组 一个      更新时间:2023-10-16

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

这个怎么样?

  1. 分配一个数组,包含从0到arrayLength-1的数字
  2. 打乱数组
  3. 如果数组中没有元素的索引等于它的值,继续步骤4;否则重复步骤2。
  4. 使用洗牌数组值作为数组的索引。
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

这保证每个值不在它开始的位置,但不保证如果有重复的值,每个值都会改变。

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

这不是随机的,但你可以旋转所有的元素至少一个位置:

std::rotate(v.begin(), v.begin() + (rand() % v.size() - 1) + 1, v.end());

如果v在开始时是{1,2,3,4,5,6,7,8,9},那么在旋转后它将是,例如:{2,3,4,5,6,7,8,9,1}{3,4,5,6,7,8,9,1,2},等等。

数组的所有元素将改变位置

我有一个想法,希望它适合您的应用程序。再多一个集装箱,这个集装箱将是"地图(int,向量(int))"。键元素将显示索引,第二个元素(vector)将保存已使用的值。

例如,对于第一个元素,您将使用rand函数来查找应该使用数组中的哪个元素。如果数组的此元素已用于此索引,则将检查映射结构。