zoukankan      html  css  js  c++  java
  • 不重复随机数生成

      在服务器里面需要用到从一组数中随机M个不同的数出来的需要,这种需求实现出来本身不复杂,最简单的就是一直随机,每次随机出来的数字判断是否跟之前有重复,如果没有就加入返回队列中。这种简单的算法在数据源很大,需要随机的数很少的时候,效率还是可以的,而且实现非常简单。但是在数据源本身就很小,而且需要随机的数据量比数据源差不都,那么就可能会发生需要随机多次才能随机出一个和现有随机数不同的数值,那么可能导致算法效率非常低下。

      通过google了一些不同的随机算法之后,结合这个需要本身,针对数组下标替换算法进行了部分修改。主体的算法还是通过随机索引和当前数组的索引进行交换,然后当前索引后移,继续进行随机交换。这个算法需要注意的地方,就是数据源本身在进入算法之前需要按照数据范围进行排序初始化。

      算法实现的代码如下:

     1     void GenUniRandVec(vector<uint32_t>& orignVec, uint32_t uOrignSize, uint32_t uNum, vector<uint32_t>& randVec)
     2     {
     3         if (uNum > uOrignSize)                    // 超过能随机的范围
     4         {
     5             return;
     6         }
     7 
     8         /*
     9             采用数组下标置换的方式,传入的orignVec需要是指定随机范围内数字排序好之后的数组
    10             如果获得了指定数量的随机值后,算法就终止
    11         */
    12         uint32_t uRandCount = 0;
    13         for (uint32_t i=0; i<uOrignSize; i++)
    14         {
    15             if (uRandCount == uNum)
    16             {
    17                 break;
    18             }
    19 
    20             if (i+1 == uOrignSize)
    21             {
    22                 return;
    23             }
    24 
    25             // 在min和max之间随机一个数字
    26             uint32_t uRandIndex = GenRandom(i+1, uOrignSize);
    27 
    28             // 置换元素下标
    29             std::swap(orignVec[i], orignVec[uRandIndex]);
    30             randVec.push_back(orignVec[i]);
    31             ++uRandCount;
    32         }
    33 
    34         return;
    35     }

      当随机出指定数量的不重复随机数之后,函数就退出。

      这个算法不能用作数量非常大的数据源,会导致orignVec在初始化的时候需要非常长的时间。这种数据量非常大的数据源,就可以直接进行随机,如果发生重复再随机可以。

  • 相关阅读:
    编译hadoop eclipse的插件(hadoop1.0)
    HBase体系结构剖析
    hadoop2.6完全分布式安装HBase1.1
    HDFS主要特性和体系结构
    一些C语言学习的国外资源
    一个监控系统进程网络流量的程序
    python解析发往本机的数据包示例 (解析数据包)
    使用Fiddler抓包调试https下的页面
    fiddler Android下https抓包全攻略
    C++使用hiredis连接带密码的redis服务
  • 原文地址:https://www.cnblogs.com/chobits/p/4026898.html
Copyright © 2011-2022 走看看