程序员面试金典——解题总结: 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; }
相关文章推荐
- 编写一个方法,洗一副牌。要求做到完美洗牌,换言之,这幅牌52!种排列组合出现的概率相同。假设给定一个完美的随机发生器
- 程序员面试金典——解题总结: 9.18高难度题 18.3编写一个方法,从大小为n的数组中随机选出m个整数。要求每个元素被选中的概率相同。
- 程序员面试金典——解题总结: 9.18高难度题 18.4编写一个方法,数出0到n(含)中数字2出现了几次
- 程序员面试金典——解题总结: 9.18高难度题 18.7给定一组单词,编写一个程序,找出其中的最长单词,且该单词由这组单词中的其他单词组合而成。
- 程序员面试金典——解题总结: 9.18高难度题 18.9随机生成一些数字并传入某个方法。编写一个程序,每当收到新数字时,找出并记录中位数。
- 程序员面试金典——解题总结: 9.18高难度题 18.10给定两个字典里的单词,长度相等。编写一个方法,将一个单词变换成另一个单词,一次只改动一个字母。
- 程序员面试金典——解题总结: 9.18高难度题 18.8给定一个字符串s和一个包含较短字符串的数组T,设计一个方法,根据T中的每一个较短字符串,对s进行搜索
- 程序员面试金典——解题总结: 9.18高难度题 18.12给定一个正整数和负整数组成的N*M矩阵,编写代码找出元素总和最大的子矩阵。
- 程序员面试金典——解题总结: 9.18高难度题 18.1编写一个函数,将两个数字相加。不得使用+或其他算术运算符。
- 程序员面试金典——解题总结: 9.17中等难题 17.4编写一个方法,找出两个数字中最大的那一个。不得使用if-else或其他比较运算符。
- 程序员面试金典——解题总结: 9.17中等难题 17.9设计一个方法,找出任意指定单词在一本书中的出现频率
- 程序员面试金典——解题总结: 9.17中等难题 17.11给定rand5(),实现一个方法rand7()。也就是,给定一个产生0到4(含)随机数的方法,编写一个产生0到6(含)随机数的方法
- 程序员面试金典——解题总结: 9.18高难度题 18.6设计一个算法,给定10亿数字,找出最小的100万个数字。假定计算机内存足以容纳全部10亿个数字。
- 程序员面试金典——解题总结: 9.18高难度题 18.8---拓展: 实现一个Trie树
- 程序员面试金典——解题总结: 9.18高难度题 18.13给定一份几百万个单词的清单,设计一个算法,创建由字母组成的最大矩形
- 程序员面试金典——解题总结: 9.18高难度题 18.11给定一个方阵,其中每个单元(像素)非黑即白。设计一个算法,找出四条边都是黑色像素的最大子方阵。
- 程序员面试金典——解题总结: 9.18高难度题 18.5有个内含单词的超大文本文件,给定任意两个单词,找出在这个文件中这两个单词的最短距离
- 假设有两个按元素值递增有序排列的线性表A和B,均以单链表作存储结构,请编写算法将A表和B表归并为一个按元素值递减 有序(即非递增有序,允许表中含有值相同的元素)排列的线性表C,并要求利用原装(即A表和
- 程序员面试金典——解题总结: 9.17中等难题 17.1编写一个函数,不用临时变量,直接交换两个数
- 程序员面试金典——解题总结: 9.17中等难题 17.6给定一个整数数组,编写一个函数,找出索引m和n,只要将m和n之间的元素排好序,整个数组就是有序的。注意:n - m越小越好,也就是说,找出