关于产生不重复随机数的算法 C#

咱们不得不认可这样一个事实:那就是尽管在高级程序语言设计中包含了相似于Random产生随机数之类的方法,可是它产生的随机数并不能知足咱们平常全部须要,由于它可能重复——设想一下,电子化抽取试题的原理就是根据预约产生的题目数量产生果敢若干个对应的随机数,而后将匹配的试题抽取、排序并打印在试卷上。可是在同一次考试时候不容许同一题目出现重复(尽管这样的几率很低,可是咱们绝对不容许这样作!)。因此避免产生重复随机数的方法(产生“真正的随机数”)成了咱们必须研究的话题。今天本文就讨论一下。php


方法1:去重法
这是最容易想到的方法,逐个产生这些随机数,每产生一个,都跟前面的随机数比较,若是重复,就从新产生。 这种方法效率比较低,且比较次数呈线性增加,越日后次数越多。


方法2:筛选法

所谓“筛选法”就是根据要产生随机数指定的范围(起始数必须小于终止数),将这些数所有装入一个数组,而后利用系统随机函数(好比 Random )随机产生一个下标,将这个下标对应的数值返回并删除对应的这个数,直到这个数组为空。 html

public sealed class TureRandom  
{  
    private ArrayList nums=new ArrayList();  
  
    public TureRandom (int startnum, int endnum)  
    {  
        if (startnum >= endnum)   
            throw new Exception("对不起,起始数字必须小于结尾数字!")  
        else  
           for (int i=startnum; i<=endnum;++i)  
                nums.Add(i);  
         
    }  
  
    public int GetNum()  
    {  
        if (nums.Count <= 0) Then  
            throw new Exception("对不起,指定范围的随机数所有产生过了。")  
        else  
          {  
            Random r = new Random();  
            int index=(int)(r.NextDouble()*10+1);  
            int returnnum =(int)(nums[index]);  
            nums.RemoveAt(index);  
            return returnnum;  
            }  
    }  
}  

方法3:

int a[100]={0};
int i, m;
for(i=1; i<=99; ++i)
{
        while(a[m=rand()%100]);
        a[m] = i;
}

这段代码也是随机产生位置,但它预先把整个数组初始化为0,而后随机产生其中一个位置,若是该元素 值为0,表示这个位置尚未被使用过,就把i赋予它;不然,就从新随机产生另外一个位置,直到整个数组 被填满。


方法4:
算法

int a[100];
for(i=0; i<=99; ++i) a[i]=i;
for(i=99; i>=1; --i) swap(a[i], a[rand()%i]);

上面这段代码只须要遍历一次就能够产生这100个不重复的随机数,它是如何作到的呢?首先第二行按顺 序用0到99填满整个数组;第三行,是随机产生从0到m-2个数组下标,把这个下标的元素值跟m-1下标的元 素值交换,一直进行到下标为1的元素。所以它只须要遍历一次就能产生所有的随机数。


转载出处:http://blog.chinaunix.net/uid-20384806-id-1954354.html数组

关于这些方法中算法的性能和效率,参阅:http://www.cnblogs.com/eaglet/archive/2011/01/17/1937083.html。dom

      http://www.nowamagic.net/program/program_GenerateRandomNumbers.php函数

相关文章
相关标签/搜索