C++ 如何洗牌数组以使所有元素改变其位置
我需要洗牌一个数组,这样所有数组元素都应该改变它们的位置。 给定一个数组C++ 如何洗牌数组以使所有元素改变其位置,c++,random,shuffle,C++,Random,Shuffle,我需要洗牌一个数组,这样所有数组元素都应该改变它们的位置。 给定一个数组[0,1,2,3]可以得到[1,0,3,2]或[3,2,0,1],但不能得到[3,1,2,0](因为2保持不变)。 我猜想算法不是语言特定的,但在这种情况下,我需要在C++程序中使用它(并且我不能使用 STD::RealthyStuffle < /Cube >由于附加的要求)。 < P>它不会是非常随机的,但是你可以将所有元素旋转至少一个位置: std::rotate(v.begin(), v.begin() + (rand
[0,1,2,3]
可以得到[1,0,3,2]
或[3,2,0,1]
,但不能得到[3,1,2,0]
(因为2
保持不变)。
我猜想算法不是语言特定的,但在这种情况下,我需要在C++程序中使用它(并且我不能使用<代码> STD::RealthyStuffle < /Cube >由于附加的要求)。 < P>它不会是非常随机的,但是你可以将所有元素旋转至少一个位置:
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}
,等等
数组的所有元素都将改变位置
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
这可以保证每个值都不在其开始的位置,但不能保证在存在重复值时每个值都会更改
注意,虽然简单,但这是有缺陷的。给定列表[0,1,2,3],此算法无法生成输出[1,0,3,2]。这怎么办
我有一个想法,希望它适合你的申请。再有一个容器,此容器将 一个“映射(int,向量(int))”。键元素将显示索引,向量的第二个元素将保存已使用的值
例如,对于第一个元素,您将使用rand函数查找应使用的数组元素。然后,如果数组的此元素已用于此索引,您将检查映射结构 你有内存需求吗?您可以创建一个与第一个数组大小相同的新数组,然后将array1中的每个元素移动到array2中一个新的随机位置。如果已设置该值,请重试。另一种方法:从索引0开始,用随机的其他索引交换它。保留已交换的所有索引的列表。在列表上迭代,只交换未交换的项。最简单的方法,虽然完全不是随机的-将所有数组元素移动x个位置。在任何语言中都应该很容易做到,只需创建一个新数组,以偏移量复制第一个数组,然后在开始时复制其余的数组。为什么不能使用
std::random_shuffle
?答案是否必须避免所有的
?所有的C++库?所有的图书馆?听起来你在寻找一个随机的疯子。有关算法,请参阅。此解决方案有问题吗?这不会洗牌数组。它给出了一个可预测的结果。简单正确的解决方案。我不认为有任何理由在解决方案中包含随机性,它与所述问题无关。即使结果是可预测的,原始问题中可接受的“解决方案”之一表明这是可以的<代码>[0,1,2,3]可以变成[3,1,2,0]
。它改变每个元素的位置。你是从哪里得到关于洗牌的定义的,它是一种不能给出可预测结果的操作?很抱歉,关于“map(int,vector(int)),我不知道如何使用它“我相信这是Fisher-Yates shuffle的一个变种,被称为。这是一个非常简单的算法,如果没有人想到它,我会感到惊讶。”。我听说过费舍尔·耶茨,但以前没有听说过萨托洛。这并没有造成所有可能的混乱。考虑列表<代码> [01,1,3] 和上面允许的第一个输出:<代码> [1,03.2,2] < /代码>。此输出永远无法生成!请注意,在最后一步(即将交换3),列表看起来像[?,?,X,3]
,其中X
不能为2,因为它在上一步中刚刚交换到?
位置之一。因此,X
在最后一步之后以3结尾的唯一方法是,列表看起来像[?,?,3,X]
,X不能是2,因此无法生成排列。这种算法只产生了一小部分可能的精神错乱。@BeeOnRope:5年内,没有人注意到这一点。做得好!修正了。新算法只是一个(Fisher-Yates)洗牌-元素可以在开始的地方结束,违反了OPs要求。顺便说一句,据我所知,没有简单的直接产生混乱的算法——论文都是关于现存的算法写的。一种合理的概率方法就是如上所述生成一个洗牌,然后检查是否有任何元素留在原地,如果有则重试。这似乎很好,因为您可以将洗牌外包给std::random_shuffle
,洗牌似乎是最难的部分。这可以生成所有可能的允许输出,与公认的答案不同。