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

时间:2013-02-26 18:06:39

标签: c++ random shuffle

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

4 个答案:

答案 0 :(得分: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

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

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

答案 1 :(得分:5)

这个怎么样?

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

答案 2 :(得分: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}等。

数组的所有元素都会改变位置。

答案 3 :(得分:1)

我心中有一种想法希望它适合您的应用。还有一个容器和这个容器 “map(int,vector(int))”。关键元素将显示索引,第二个元素将包含已使用的值。

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