洗牌算法
Iterative solution: 对于每一张牌,card[i]只要和[0 , i ] 中任意(random)一张牌swap就可以
写一个随机洗牌函数。要求洗出的52!种组合都是等概率的。 也就是你洗出的一种组合的概率是1/(52!)。假设已经给你一个完美的随机数发生器。
问题:每次随机取出一张牌,要注意已经取出的牌不会在剩余牌中,这样如果只用random函数,就需要限定范围。否则可能产生的随机数相同
解决方法:
如果有shuttle函数,对n-1张牌有效,用这个函数洗n张牌?
n-1张牌洗牌后,顺序是随机的,这样只要将第n张牌与数组中任意一个元素swap就可以。(包含其本身位置)--可由归纳法推导得出满足题目要求的概率
(1)shuffle first n -1 cards
(2) take the nth element and randomly swap it with an element in the array
(2) take the nth element and randomly swap it with an element in the array
public int[] shuffle(int[] cards, int n){
if( i== 0) return cards; // no need to shuffle
shuffle(cards, n-1);
int randomnum = random(0, n);
//swap
int tmp = cards[n];
cards[n] = cards[randomnum];
cards[randomnum] = tmp;
return cards;
}
private int random(int l, int h){
//get a random number in range[l, h]
int num = l + (int)(Math.random() * (h - l + 1));
return num;
}
Iterative solution: 对于每一张牌,card[i]只要和[0 , i ] 中任意(random)一张牌swap就可以
public void shuffle(int[] cards){
if( i== 0) return; // no need to shuffle
for(int i = 0; i < cards.length; i++){
int k = random(0, i);
//swap
int tmp = cards[i];
cards[i] = cards[k];
cards[k] = tmp;
}
}