//洗牌算法
list = new ArrayList<Integer>();
for(int i= 1; i<=total; i++){
list.add(i);
}
for(int i=0; i< total; i++){
position = r.nextInt(total - i);
swap(list,i, i + position);
}
for(int i = 0; i < total; i++){
p[i%div][i/div] = list.get(i);
}
print(p);
swap方法为:
//交换list中的元素
public static void swap(List<Integer> list,int a, int b){
int t = list.get(a);
list.set(a, list.get(b));
list.set(b, t);
}
http://25zhangshaoyang.blog.163.com/blog/static/2014175120118158499551/
风云的blog也谈到洗牌算法:
http://blog.codingnow.com/2007/09/shuffle.html#comments
http://www.thecodeway.com/blog/?p=680
每次随机抽出两张牌交换,重复交换一定次数次后结束
void shuffle(int* data, int length)
{
for(int i=0; i<SWAP_COUNTS; i++)
{
//Rand(min, max)返回[min, max)区间内的随机数
int index1 = Rand(0, length);
int index2 = Rand(0, length);
std::swap(data[index1], data[index2]);
}
}
这又是一个常见的洗牌方法,比较有意思的问题是其中的“交换次数”,我们该如何确定一个合适的交换次数?简单的计算,交换m次后,具体某张牌始终没有被抽到的概率为((n-2)/n)^m,如果我们要求这个概率小于1/1000,那么m>-3*ln(10)/ln(1-2/n),对于52张牌,这个数大约是176次,需要注意的是,这是满足“具体某张牌”始终没有被抽到的概率,如果需要满足“任意一张牌”没被抽到的概率小于1/1000,需要的次数还要大一些,但这个概率计算起来比较复杂,有兴趣的朋友可以试一下