洗牌算法或者叫打乱数组顺序算法

for(int i = n - 1; i >= 0 ; i -- )
    swap(arr[i], arr[rand(0, i)]) // rand(0, i) 生成 [0, i] 之间的随机整数

从后往前交换是因为生成 [0, i] 范围的随机数比生成 [i, n) 范围的随机数简单,直接对 i+1 求余就好了。

n个数有n!种组合,这样交换可以实现产生的每个组合是等可能的。

有一个大小为100的数组,里面的元素是从 1 到 100 按顺序排列,怎样随机的从里面选择 50 个数?注意数字不能重复!

就可以先打乱在取其中50个。直接产生随机数作为下标是会重复的。

或者弄一个数组,把每一次随机的数都放到数组里,下一次随机就看这个数组里面有没有这数,有的话就继续随机,直到这个数组里面有 50 个数字就停止。这个可以,但是,越往后选择的数字跟前面已经挑选的数字重复的概率越高,这就会造成如果数组很大,选择的数字数目也很大的话,重复次数在量级上会很大。

发布了78 篇原创文章 · 获赞 20 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43657442/article/details/104779582