18.2 编写一个方法,洗一副牌。要求做到完美洗牌,换言之,这幅牌52!种排列组合出现的概率相同。假设给定一个完美的随机发生器。
解法:假定有个数组,含有n个元素,类似如下:
[1][2][3][4][5]
利用简单构造法,我们不妨先问自己,假定有个方法shuffle(...)对n-1个元素有效,我们可以用它来打乱n个元素的次序吗?当然可以,而且非常容易实现。我们会先打乱前n-1个元素的次序,然后,取出第n个元素,将它和数组中的元素随机交换。就这么简单!递归解法的算法如下:
//lower和highter(含)之间的随机数 int rand(int lower,int highter) { return lower+(int)(random()*(highter-lower+1)); } void shuffleArrayRecursively(int cards[],int i) { if(i==0) return; shuffleArrayRecursively(cards,i-1); int k=rand(0,i); int temp=cards[i]; cards[i]=cards[k]; cards[k]=temp; return; }
以迭代方式实现的话,这个算法又会是什么样?让我们先考虑,我们要做的是遍历整个数组,对每个元素i,将array[i]与0到i(含)之间的随机数交换。
void suffleArrayInteratively(int cards[],n) { for(int i=0;i<n;i++) { int k=rand(0,i); int tmp=cards[k]; cards[k]=cards[i]; cards[i]=tmp; } }
原文:http://www.cnblogs.com/wuchanming/p/4361827.html