这个C执行Fisher-Yates洗牌是否正确?

前端之家收集整理的这篇文章主要介绍了这个C执行Fisher-Yates洗牌是否正确?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_403_0@
以下是Fisher-Yates的C实现,我想使用一个甲板洗牌程序.我正在做这个(n =数组的长度)?

注意:do-while循环尝试纠正模偏(见here).它为该过程增加了一些开销,如果不关心低位偏差,可以消除该过程.

  1. void shuffle(int *array,int n) {
  2.  
  3. int i,j,tmp,upper_bound;
  4.  
  5. srand(time(NULL));
  6.  
  7. for (i = n - 1; i > 0; i--) {
  8.  
  9. upper_bound = RAND_MAX - ((RAND_MAX % (i + 1)) + 1);
  10.  
  11. do {
  12. j = rand() % (i + 1);
  13. } while (j > upper_bound);
  14.  
  15. tmp = array[j];
  16. array[j] = array[i];
  17. array[i] = tmp;
  18. }
  19. }

解决方法

首先,您应该提取用于生成在0(包括)和n(独占)之间均等分配到一个单独的函数随机数的代码.这也是您在其他地方需要工作的一项不错的工作.

第二,我不会在洗牌功能调用srand,而是依赖于调用者初始化随机生成器.这样你可以在一秒钟内洗牌一次以上.

第三,你应该做j>的测试. upper_bound除以i 1.我不大可能会接近RAND_MAX.

  1. static int rand_int(int n) {
  2. int limit = RAND_MAX - RAND_MAX % n;
  3. int rnd;
  4.  
  5. do {
  6. rnd = rand();
  7. } while (rnd >= limit);
  8. return rnd % n;
  9. }
  10.  
  11. void shuffle(int *array,int n) {
  12. int i,tmp;
  13.  
  14. for (i = n - 1; i > 0; i--) {
  15. j = rand_int(i + 1);
  16. tmp = array[j];
  17. array[j] = array[i];
  18. array[i] = tmp;
  19. }
  20. }

要检查此实现是否正确,您需要确保随机生成器询问log2(n!)位的随机性.换句话说,给予rand_int函数的所有ns的乘积必须是n!

猜你在找的C&C++相关文章