熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

用C#生成不重復的隨機數

2013-11-13 12:20:03  來源: .NET編程 

  我們在做能自動生成試卷的考試系統時常常需要隨機生成一組不重復的題目net Framework中提供了一個專門用來產生隨機數的類SystemRandom

  對於隨機數大家都知道計算機不可能產生完全隨機的數字所謂的隨機數發生器都是通過一定的算法對事先選定的隨機種子做復雜的運算用產生的結果來近似的模擬完全隨機數這種隨機數被稱作偽隨機數偽隨機數是以相同的概率從一組有限的數字中選取的所選數字並不具有完全的隨機性但是從實用的角度而言其隨機程度已足夠了偽隨機數的選擇是從隨機種子開始的所以為了保證每次得到的偽隨機數都足夠地隨機隨機種子的選擇就顯得非常重要如果隨機種子一樣那麼同一個隨機數發生器產生的隨機數也會一樣一般地我們使用同系統時間有關的參數作為隨機種子這也是net Framework中的隨機數發生器默認采用的方法

  我們可以使用兩種方式初始化一個隨機數發生器

  第一種方法不指定隨機種子系統自動選取當前時間作為隨機種子

  Random ro = new Random();

  第二種方法可以指定一個int型參數作為隨機種子

  int iSeed=;
  Random ro = new Random();
  long tick = DateTimeNowTicks;
  Random ran = new Random((int)(tick & xffffffffL) | (int) (tick >> ));

  這樣可以保證%不是一樣

  之後我們就可以使用這個Random類的對象來產生隨機數這時候要用到RandomNext()方法這個方法使用相當靈活你甚至可以指定產生的隨機數的上下限

  不指定上下限的使用如下

  int iResult;
  iResult=roNext();

  下面的代碼指定返回小於的隨機數

  int iResult;
  int iUp=;
  iResult=roNext(iUp);

  而下面這段代碼則指定返回值必須在的范圍之內

  int iResult;
  int iUp=;
  int iDown=;
  iResult=roNext(iDowniUp);

  除了RandomNext()方法之外Random類還提供了RandomNextDouble()方法產生一個范圍在之間的隨機的雙精度浮點數

  double dResult;
  dResult=roNextDouble();

  但是用Random類生成題號會出現重復特別是在數量較小的題目中要生成不重復的的題目是很難的參考了網上的一些方法包括兩類一類是通過隨機種子入手使每一次的隨機種子不同來保證不重復;第二類是使用一些數據結構和算法下面主要就第二類介紹幾個方法

  方法思想是用一個數組來保存索引號先隨機生成一個數組位置然後把這個位置的索引號取出來並把最後一個索引號復制到當前的數組位置然後使隨機數的上限減一具體如先把這個數放在一個數組內每次隨機取一個位置(第一次是第二次是)將該位置的數用最後的數代替

  int[] index = new int[];
  for (int i = ; i < ; i++)
  index = i;
  Random r = new Random();
  //用來保存隨機生成的不重復的個數
  int[] result = new int[];
  int site = ;//設置下限
  int id;
  for (int j = ; j < ; j++)
  {
   id = rNext( site );
   //在隨機位置取出一個數保存到結果數組
   result[j] = index[id];
   //最後一個數復制到當前位置
   index[id] = index[site ];
   //位置的下限減少一
   site;
  }
  方法利用Hashtable[NextPage]
  Hashtable hashtable = new Hashtable();
  Random rm = new Random();
  int RmNum = ;
  for (int i = ; hashtableCount < RmNum; i++)
  {
   int nValue = rmNext();
   if (!hashtableContainsValue(nValue) && nValue != )
   {
    hashtableAdd(nValue nValue);
    ConsoleWriteLine(nValueToString());
   }
  }

  方法遞歸用它來檢測生成的隨機數是否有重復如果取出來的數字和已取得的數字有重復就重新隨機獲取

  Random ra=new Random(unchecked((int)DateTimeNowTicks));
  int[] arrNum=new int[];
  int tmp=;
  int minValue=;
  int maxValue=;
  for (int i=;i<;i++)
  {
   tmp=raNext(minValuemaxValue); //隨機取數
   arrNum=getNum(arrNumtmpminValuemaxValuera); //取出值賦到數組中
  }
  
  
  public int getNum(int[] arrNumint tmpint minValueint maxValueRandom ra)
  {
   int n=;
   while (n<=arrNumLength)
   {
    if (arrNum[n]==tmp) //利用循環判斷是否有重復
    {
     tmp=raNext(minValuemaxValue); //重新隨機獲取
     getNum(arrNumtmpminValuemaxValuera);//遞歸:如果取出來的數字和已取得的數字有重復就重新隨機獲取
    }
    n++;
   }
   return tmp;
  }


From:http://tw.wingwit.com/Article/program/net/201311/15682.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.