实现一个方法,对一副牌(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;
}