您的位置:首页 > 职场人生

程序员面试金典——解题总结: 9.18高难度题 18.2编写一个方法,洗一副牌。要求做到完美洗牌,换言之,这副牌52!种排列组合出现的概率相同

2017-01-18 00:10 483 查看
#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,调换牌
和牌[k]

关键:
1	  递归的方式就是:假设shuffle()对n-1个元素有效,如何用该方法来打乱n个元素的次序。可以先将前n-1个元素打乱,
然后从`0~n中随机选择一个数k,调换牌
和牌[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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐