不重复随机数生成

  在服务器里面需要用到从一组数中随机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在初始化的时候需要非常长的时间。这种数据量非常大的数据源,就可以直接进行随机,如果发生重复再随机可以。

时间: 2024-10-31 08:18:49

不重复随机数生成的相关文章

PHP中钩子函数的实现与认识

PHP中钩子函数的实现与认识 分类:PHP编程  作者:rming  时间:2014-09-21 假如有这么一段程序: function fun(){ fun1(); fun2(); }   首先程序执行完fun1()之后执行fun2()然后fun()结束.   但是,假如我们想对函数做一些变化.比如说,fun是一个解析函数,我们希望后期可以提供丰富的解析函数,而究竟用哪个函数解析,我们希望在配置文件中配置.这个时候就可以发挥钩子的力量了.   我们可以在function fun(){}中加入一

实用的随机数生成类Random:测试(随机产生100个不重复的正整数)

实用的随机数生成类Random:测试(使用Random类随机生成100个不重复的正整数) 一.之前我们使用随机数用的是Math类的random()方法: tips: 产生随机数(0~9中任意整数)的方法:int random = (int)(Math.random()*10); 1.商场幸运抽奖程序. 会员号的百位数字等于产生的随机数即为幸运会员. public class GoodLuck{ public static void main(String[] args){ //产生随机数 int

C# 随机数生成避免重复

public string GetMsgID() { Random rand = new Random((int)DateTime.Now.Ticks); string szRand = rand.Next(0, 9999).ToString().PadLeft(4, '0'); return string.Format("{0}{1}", DateTime.Now.ToString("yyyyMMddHHmmss"), szRand); } null

等概率无重复的从n个数中选取m个数

问题描述:程序的输入包含两个整数m和n,其中m<n.输出是0~n-1范围内的m个随机整数,要求:每个数选择出现的概率相等,且按序输出. 学习过概率统计的同学应该都知道每一个数字被抽取的概率都应该为m/n. 那么我们怎么构造出这样的概率呢?在<编程珠玑>上面是这样解析的: 依次考虑整数0,1,2,.....,n-1,并通过一个适当的随机测试对每个整数进行选择.通过按序访问整数,我们可以保证输出结果是有序的. 假如我们考虑m = 2,n = 5的情况,那么选择的每一个数字的概率都应该是2/5

产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复

写在前面 前天去面试了,给出的笔试中有这样的一道算法题,产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复 当时,脑子一热,也没想那么多,就用集合实现了一下,经面试官提醒,发现还有更好的方式来实现. 代码 首先看一下这样一段代码 1 namespace Wolfy.RandomDemo 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 List<int> lst = new List<i

转:在0~N(不包括N)范围内随机生成一个长度为M(M &lt;= N)且内容不重复的数组

1. 最朴素暴力的做法. void cal1() { int i = 0, j = 0, num = 0; int result[M]; result[0] = rand() % N; //第一个肯定不重复, 直接加进去 for (i = 1; i < M; i++) //获得剩下的(M-1)个随机数 { num = rand() % N; //生成0 ~ N之间的随机数字 for (j = 0; j < i; j++) { if (num == result[j]) //如果和result数

导入random模块, 生成0-100间所有数字的随机列表(列表中的数字不重复)

导入random模块, 生成0-100间所有数字的随机列表(列表中的数字不重复)思路:先导入随机数生成模块,通过循环生成随机数,判断生成随机数是否有相同的,把不同的写入列表 方法一:方法二: 欢迎各路大神指正 原文地址:http://blog.51cto.com/10412806/2088010

cookie和session页面随机数和防止重复提交

http 无状态的协议,每次请求都是独立的我们不能存储第一次访问的数据 Cookie 实现访问请求的数据保存 将服务器中的一小段,存入浏览器中放在浏览器中的cookie中,是存入浏览器中. 优点:减少服务器的压力 缺点:不安全,存储的数据单一,只能为字符串,可以通过路由器获得所有的cookie 1. 添加cookie 2. 获得cookie 3. 解决中文乱码问题 4. 修改cookie的两种方式(cookie为键值对,key值不能重复,或者cookie.setvalues()) 5. 生命周期

LeetCode 442. Find All Duplicates in an Array (在数组中找到所有的重复项)

Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements that appear twice in this array. Could you do it without extra space and in O(n) runtime? Example: Input: [4,3,2,7,