#include <iostream>
#include <stdio.h>
#include <vector>
#include <sstream>
using namespace std;
/*
问题:编写一个方法,洗一副牌。要求做到完美洗牌,换言之,这副牌52!种排列组合出现的概率相同。假设给定一个完美的
随机数发生器。
分析:之前的洗牌方式是,遍历52张牌,对当前牌i,获取1到52中的随机数index,将牌i和牌index进行调换。
这个方法是否符合52!概率相同?这个应该是符合的
递归的方式就是:假设shuffle()对n-1个元素有效,如何用该方法来打乱n个元素的次序。可以先将前n-1个元素打乱,
然后从`0~n中随机选择一个数k,调换牌[n]和牌[k]
关键:
1 递归的方式就是:假设shuffle()对n-1个元素有效,如何用该方法来打乱n个元素的次序。可以先将前n-1个元素打乱,
然后从`0~n中随机选择一个数k,调换牌[n]和牌[k]
vector<int> shuffle(vector<int>& cards , int n)
{
//对第0张牌,只剩一张,无法进行洗牌,返回
if( 0 == n)
{
return cards;
}
//打乱前n-1张牌
shuffle(cards , n-1);
int k = randMinMax(0 , n);//随机挑选索引交换
int temp = cards.at(k);
cards.at(k) = cards.at(n);
cards.at(n) = temp;
return cards;
}
*/
int randMinMax(int min ,int max)
{
if(min > max)
{
stringstream stream;
stream << "min:" << min << ",max:" << max << " is wrong! min must less than max";
throw(stream.str());
}
return (rand() % (max - min + 1) + min);
}
vector<int> shuffle(vector<int>& cards , int n)
{
//对第0张牌,只剩一张,无法进行洗牌,返回
if( 0 == n)
{
return cards;
}
//打乱前n-1张牌
shuffle(cards , n-1);
int k = randMinMax(0 , n);//随机挑选索引交换
int temp = cards.at(k);
cards.at(k) = cards.at(n);
cards.at(n) = temp;
return cards;
}
void process()
{
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}