https://www.cnblogs.com/soulmate/p/5607060.html
.net.Framework中提供了一個專門產生隨機數的類System.Random,此類默認狀況下已被導入,編程過程當中能夠直接使用。html
咱們知道,計算機並不能產生徹底隨機的數字,它生成的數字被稱爲僞隨機數,它是以相同的機率從一組有限的數字中選取的,所選的數字並不具備徹底的隨機性,但就實用而言,其隨機程度已經足夠了。算法
咱們能夠用如下兩種方法初始化一個隨機數發生器;編程
函數是這樣用,好比100至999的隨機數
Random ran=new Random();
int RandKey=ran.Next(100,999);
不過這樣會有重複,能夠給Random一個系統時間作爲參數,以此產生隨機數,就不會重複了 數組
第一種方法
不指定隨機種子,系統自動選取當前時前做隨機種子:(Random ra = new Random(DateTime.Now.Millisecond);)
Random ra=new Random(); dom
第二種方法
是指定一個int型的參數做爲隨機種子:
int iSeed=6;
Random ra=new Random(iSeed);
下面咱們要用到Random.Next()方法產生隨機數。
ra.Next();
它返回一個大於或等於零而小於2,147,483,647的數,這並不知足咱們的須要,下面咱們介紹它的重載函數和其它一些方法。
public virtual int Next(int);
用法:ra.next(20)
返回一個小於所指定最大值(此處爲20)的正隨機數。
public virtual int Next(int minValue, int maxValue);
用法:ra.next(1,20)
返回一個指定範圍內(此處爲1-20之間)的隨機數,左閉右開,咱們在下面的實例中會用到此函數。
類System.Random還有幾個方法分別是:
公共方法:
NextBytes用隨機數填充指定字節數組的元素。
NextDouble返回一個介於 0.0 和 1.0 之間的隨機數。
受保護的方法:
Sample返回一個介於 0.0 和 1.0 之間的隨機數,只容許子類對象訪問。
以上介紹了隨機數的基本用法,下面咱們用一個實例來作更進一步的介紹。要在一段數字區間內隨機生成若干個互不相同的隨機數,好比在從1到20間隨機生成6個互不相同的整數。
主要是下面兩個函數getRandomNum與getNum:
public int[] getRandomNum(int num,int minValue,int maxValue)
{
Random ra=new Random(unchecked((int)DateTime.Now.Ticks));
int[] arrNum=new int[num];
int tmp=0;
for (int i=0;i<=num-1;i++){
tmp=ra.Next(minValue,maxValue); //隨機取數
arrNum[i]=getNum(arrNum,tmp,minValue,maxValue,ra); //取出值賦到數組中
}
return arrNum;
}
getRandomNum便是在區間[minValue,maxValue]取出num個互不相同的隨機數,返回的數組包含着結果。
其中隨機數是這樣建立的 Random ra=new Random(unchecked((int)DateTime.Now.Ticks));爲何不用Random ra=new Random();(系統自動選取當前時前做隨機種子)呢?
用系統時間作隨機種子並不保險,若是應用程序在一個較快的計算機上運行,則該計算機的系統時鐘可能沒有時間在此構造函數的調用之間進行更改,Random 的不一樣實例的種子值可能相同。這種狀況下,咱們就須要另外的算法來保證產生的數字的隨機性。因此爲了保證產生的隨機數足夠"隨機",咱們不得不使用複雜一點的方法來得到隨機種子。在上面的這段程序中,咱們首先使用系統時間做爲隨機種子,而後將上一次產生的隨機數跟循環變量和一個與系統時間有關的整型參數相乘,以之做爲隨機種子,從而獲得了每次都不一樣的隨機種子,保證了產生足夠"隨機"的隨機數。
函數getNum是一遞歸,用它來檢測生成的隨機數是否有重複,若是取出來的數字和已取得的數字有重複就從新隨機獲取。值得注意的是要用一同一個隨機數實例生成,因此ra要做爲參數傳入getNum中,不然生成的數字會有重複。
public int getNum(int[] arrNum,int tmp,int minValue,int maxValue,Random ra){
int n=0;
while (n<=arrNum.Length-1)
{
if (arrNum[n]==tmp) //利用循環判斷是否有重複
{
tmp=ra.Next(minValue,maxValue); //從新隨機獲取。
getNum(arrNum,tmp,minValue,maxValue,ra);//遞歸:若是取出來的數字和已取得的數字有重複就從新隨機獲取。
}
n++;
}
return tmp;
}
最後就是要顯示出來,當點擊一個button時取出的數字顯示在一個label中。
private void button1_Click(object sender, System.EventArgs e)
{
int[] arr=getRandomNum(6,1,20); //從1至20中取出6個互不相同的隨機數
int i=0;
string temp="";
while (i<=arr.Length-1){
temp+=arr[i].ToString()+"\n";
i++;
}
label1.Text=temp; //顯示在label1中
}函數
開始是介紹一下random()函數和Math.random()函數,而後介紹一些由此引出的自定義函數.對於如何實戰出一些效果,那須要想象的翅膀和其它AS基礎的支持.而算法自己並不困難.最後我會介紹一個簡單效果.但願能啓發讀者的思惟.post
Random.Next() 返回非負隨機數;url
Random.Next(Int) 返回一個小於所指定最大值的非負隨機數spa
Random.Next(Int,Int) 返回一個指定範圍內的隨機數
一、random(number)函數介紹
見幫助文檔,簡單再提一下,random(number)返回一個0~number-1之間的隨機整數.參數number表明
一個整數.
示例:
trace(random(5));
//複製到主場景第一幀.
二、Math.random()
見幫助文檔。返回一個有14位精度的0~1之間的數,注意沒有參數。據說MM是推薦用這個函數的,而不是上面那個.
示例:
trace(Math.random());
//複製到主場景第一幀.
三、自定義的函數
MM給咱們的就這兩個函數了,可是需求與供給老是存在矛盾。咱們有時候須要的隨機數可不是這麼簡單。
好比咱們想返回一個有兩位小數的隨機數,返回兩個數之間的隨機數,返回字母隨機數,返回多個隨機數等等,
這些都須要咱們本身編寫函數來實現。下面的代碼直接複製到主場景第一幀就能夠調用了。注意有的函數須要入口參數。
# 返回一個共有n位數,其中m位是小數的隨機數
function randomXiao(n,m){
var a = Math.pow(10, n+m);
var b = random(a);
return b=b/Math.pow(10, m);
}
能夠用trace(randomXiao(3,2));實驗一下。這個函數簡單。Math.pow(n,m)用於返回一個以n爲底,m爲指數的數。乘方!
# 返回一個n到m之間的隨機數
function randomNm(n,m){
if(m>=n){
return random(m-n+1)+n;
}
else {
return false;
}
}
之因此用random(m-n+1)是由於隨機數的範圍是m-n,加上1使得m也能在裏面。加上n保證隨機數以n爲下限。
加上判斷使函數更完整。另外,若是要返回一個負數隨機數,也能夠用randomNm(n,0);固然,我想更通常的是用-random(n);
# 返回一個字母
function randomAscii(){
var c = String.fromCharCode(random(26)+65);
if(random(2)){
return c.toLowerCase();
}
return c;
}
返回一個不區分大小寫的隨機字母
若是要返回大寫,把if條件句去掉就好了。若是要返回小寫,能夠把條件句改成恆成立,或者去掉條件,最後一句改成:
return c.toLowerCase(); String.fromCharCode(number)函數返回number表明數字的ASCII碼。
toLowerCase()用於將大寫字母轉爲小寫。
# 返回一個n到m之間的k個互異隨機數
function randomKdiffer(n,m,k){
arrayK = [];
var i = 0;
while (i < k) {
a = random(m-n+1)+n;
for (var j = 0; j < i; j++) {
if (a == arrayK[j]) {
break;
}
}
if (j == i) {
arrayK[i] = a;
i++;
}
}
return arrayK;
}
數組arrayK中的元素即爲所得值。注意到咱們借用了random(m-n+1)+n來返回一個n~m的隨機數。因此m自己也會被返回。
若是要返回m之內的數,能夠把n值改成0。若是要隨機返回不肯定個數,能夠把入口參數的K值賦爲k=random(m-n);
隨機返回不必定互異的數,把判斷去掉就能夠了,注意i++不要漏掉。這裏再也不給出。
#指定若干個字符/數字,而後從中隨機返回一個(或多個)字符/數字,能夠把原字符賦給一個數組,再根據數組的下標來
決定返回值。這裏再也不舉出函數,你們能夠本身嘗試。
#另需指出,對於隨機設定一個MC的顏色值,咱們較多采用mcColor.setRBG(random(0xFFFFFF));下面的例子中會有說明。
若是要指定一個色域,能夠採用上面給出的函數。若是對Color對象不太瞭解的能夠查幫助,這裏不做討論。
以上函數算是由random直接衍生的,下面再舉個例子,能夠說是衍生函數的衍生函數,其中會直接用到上面給出的函數,請注意。
#返回一個指定長度的隨機大寫英文字符串
function randomString(n){
var arrayA = randomKdiffer(1, 26, n);
var arrayB = "";
for (var i = 0; i < n; i++) {
c=String.fromCharCode(arrayA[i]+64);
/* if(random(2)){
c=c.toLowerCase();
}
*/
arrayB = arrayB+c;
}
return arrayB;
}
注意到StringCharCode方法,若是要寫成小寫,則把返回值寫成arrayB.toLowerCase();若是返回一個不區分大小寫的字符串,
則把註釋去掉.若是要返回一個不指定長度的字符串,則能夠把入口參數賦值爲random(n);這樣只指定其上限.此函數也能夠用
randomAscii函數實現,留給你們本身思考.
#在幾個區域中選出隨機數
好比,在1~20,45~70這兩段數之間選取一個隨機數。由於區域數未定,因此直接用一個肯定的函數編寫多有不便,
咱們要使用的方法就是用switch語句進行定向,具體的咱們給出一個函數,返回一個1~20,45~70內的數,其它區域讀者請自行更改。
function randomArea(){
var a=random(2);
switch(a){
case 0:
return randomNm(1,20);break;
case 1:
return randomNm(45,70);break;
}
}
注意,咱們並無寫入口參數,而是直接在函數中就肯定了是兩段數,並且範圍也是肯定的。若是是三段,則改成a=random(3);
一樣增長一個case就能夠了。固然,你也能夠把第段數的範圍設爲入口參數,這裏就再也不舉例了。可是這樣作可能會使參數增多,
我我的是不太喜歡一個須要不少參數的函數的。相似的,咱們也能夠隨機返回一個字母段或幾個字母段或者字母加數字段的一個數。
方法也只是前幾個函數的一個結合。這裏僅舉一例,返回指定的大寫字母段的一個隨機字母。
提醒一下,小寫字母的ASCII碼a~z分別對應97~122.
function randomAArea(a,b){
if (ord(a) <= ord(b) && 65<=ord(a) && ord(b) <= 90) {
return String.fromCharCode(randomNm(ord(a), ord(b)));
} else {
return false;
}
}
其中用到一個函數ord(char),這是一個不推薦的函數.用於返回char字符的ASCII碼。
若是你們想在任何地方調用函數,則須要稍稍變一下,把咱們寫的函數改變爲全局函數.這樣就能夠不用標明路徑而自如地向調用系統
函數同樣了.方法以下.例如:函數randomXiao若是要聲明爲全局函數,須要把第一行改成:
_global.randomXiao=function(n,m){
//statment
}
對全局函數的概念不很清楚的朋友不用被這個名詞嚇倒.
這樣改了函數第一行以後,在任何地方,好比在一個MC裏,直接用(對,直接用,不用加_root路徑了)randomXiao(n,m)就能夠.net
Random類是一個產生僞隨機數字的類,它的構造函數有兩種,一個是直接New Random(),另一個是New Random(Int32),前者是根據觸發那刻的系統時間作爲種子,來產生一個隨機數字,後者能夠本身設定觸發的種子,通常都是用UnCheck((Int)DateTime.Now.Ticks)作爲參數種子,所以若是計算機運行速度很快,若是觸發Randm函數間隔時間很短,就有可能形成產生同樣的隨機數,由於僞隨機的數字,在Random的內部產生機制中仍是有必定規律的,並不是是真正意義上的徹底隨機。
Random類產生隨機數字的主要辦法是Next(),Next(100)產生一個比100小的正整數,Next(1,100)在1到100中間產生一個隨機數字,而利用Ticks(以100毫秒作基礎單位的時間數量單位)來產生隨機數,仍是存在合理性的。
1 /// <summary> 2 /// 用隨機數實現一件事情出現的機率是10%,另外一件事情出現的機率是90% 3 /// </summary> 4 /// <param name="args"></param> 5 private static void Main(string[] args) 6 { 7 //string[] arr = { "10", "90", "90", "90", "90", "90", "90", "90", "90", "90" }; 8 Random ran = new Random(unchecked((int)DateTime.Now.Ticks)); 9 int num1 = 0; 10 int num2 = 0; 11 for (int i = 0; i < 100000; i++) 12 { 13 int n = ran.Next(0, 10); 14 //string str = arr[n]; 15 if (n == 0) 16 { 17 num1++; 18 } 19 else 20 { 21 num2++; 22 } 23 } 24 Console.Write(num1 + "--" + num2); 25 } 26 /// <summary> 27 ///舉例:用等差機率取0-99的整數,但讓99的出現概率最大,98比99小一點,97比98小一點,0出現的概率最小 28 /// </summary> 29 /// <param name="number"></param> 30 /// <returns></returns> 31 private static int GetRandom(int number) 32 { 33 int maxNumber = number + 1; 34 int maxRange = ((1 + maxNumber) * maxNumber) / 2; 35 Random rd = new Random(); 36 int randomNumber = Math.Abs(rd.Next() % maxRange); 37 int sum = 0; 38 for (int i = 0; i < maxNumber; i++) 39 { 40 sum += (maxNumber - i); 41 if (sum > randomNumber) 42 { 43 return i; 44 } 45 } 46 return -1; 47 }