關於產生不重複隨機數的算法 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函數

相關文章
相關標籤/搜索