实现一个方法,对一副牌(52张)进行洗牌,要求洗出的52!组合是的等概率的,即每种组合的概率为1/52!,假设已经有一个完美的随机数生成器。
思路:
思路比较直观,第一次从52张牌中随机取一张出来,概率为1/52;第二次从剩下的51张随机取一张出来,概率为1/51;以此类推最终的概率就是1/52!。接下来是如何用代码实现,当选中一张牌之后,在下次选择的时候就不能让这张牌再参与选择,这个怎么实现。
我们先假设一副牌数为5的牌:1,2,3,4,5。如果第1次随机取到的数是4, 那么我们希望参与第2次随机选取的只有1,2,3,5。既然4已经不用, 我们可以把它和1交换,第2次就只需要从后面4位(2,3,1,5)中随机选取即可。同理, 第2次随机选取的元素和数组中第2个元素交换,然后再从后面3个元素中随机选取元素,以此类推。
#include <iostream> #include <vector> using namespace std; void Swap(int& a, int& b) { int temp = a; a = b; b = temp; } void RandomShuffle(vector<int>& ivec) { int len = ivec.size(); for (int i = 0; i < len; ++i) { int temp = rand() % (len - i) + i; Swap(ivec[i], ivec[temp]); } } int main() { vector<int> ivec; for (int i = 1; i < 53; ++i) ivec.push_back(i); RandomShuffle(ivec); for (int i = 0; i < ivec.size(); ++i) cout << ivec[i] << endl; return 0; }