zoukankan      html  css  js  c++  java
  • 如何高效地产生多个不重复的随机数?

    如何高效产生多个不重复的随机数

    类型一: 完全范围内的随机数

    • 举例:  在整数1-100以内, 产生100个不同的随机整数
    • 思想:  将所有数字打乱, 按顺序选取各个数
     1 int a[100];
     2 
     3 //1.初始化:按序列号依次赋值
     4 for(int i=0; i<=99; ++i)
     5 {
     6      a[i]=i;
     7 }
     8 //2.生成不同的随机数序列
     9 for(int i=99; i>=1; --i) 
    10 {
    11      swap(a[i], a[rand()%i]);
    12 }

     上面这段代码只需要遍历一次就可以产生这100个不重复的随机数. 

    类型二: 部分范围内的多个不同的随机数

    • 举例:  在整数1-100以内, 产生20个不同的随机整数
    • 思想:  标记无冲突法
     1 void GenerateDiffNumber(int *diff,int maxn,int num)
     2 {
     3     int rnd;
     4     int *tmp;
     5     tmp = (int *)malloc(sizeof(int)*maxn);
     6 
     7     //1.初始化
     8     for (int i = 0; i < maxn; i++)
     9     {
    10         tmp[i] = i;
    11     }
    12 
    13     //2.产生num个不同的数
    14     for (int i = 0; i < num; i++)
    15     {    
    16         do 
    17         {
    18             rnd = rand() % maxn;//rnd<maxn
    19 
    20         } while (tmp[rnd]==-1);
    21 
    22         diff[i] = rnd;
    23         tmp[rnd] = -1; //该位置的数已被选择过,将其标记为-1   
    24     }
    25 
    26     free(tmp);
    27 }

    这段代码也是随机产生位置,但它预先把整个数组初始化为位置序号,然后随机产生其中一个位置,如果该元素

    值不为-1,表示这个位置还没有被使用过,就把i赋予它;否则,就重新随机产生另一个位置,直到整个数组

    被填满。这个方法,越到后面,遇到已使用过的元素的可能性越高,重复次数就越多,这是不及第一个方

    法的地方,但总的来说,效率还是不错的。

  • 相关阅读:
    BZOJ5104 二次剩余板子
    BZOJ5329 [Sdoi2018]战略游戏 圆方树+虚树
    BZOJ1095 动态点分治
    BZOJ3992: [SDOI2015]序列统计
    kd-tree板子
    thusc2018翻车记
    BZOJ5336 DP套DP
    BZOJ4316 仙人掌DP
    问题 F: 最小花费
    问题 C: 热浪
  • 原文地址:https://www.cnblogs.com/tsingke/p/5930293.html
Copyright © 2011-2022 走看看