隨機(jī)函數(shù) - 計(jì)算機(jī)術(shù)語(yǔ)
隨機(jī)函數(shù)就是產(chǎn)生數(shù)的函數(shù),是EXCEL中很重要的函數(shù),C語(yǔ)言里也有rand - ,srand - 等隨機(jī)函數(shù)。標(biāo)準(zhǔn)C庫(kù)中函數(shù)rand()可以生成0~RAND_MAX之間的一個(gè)隨機(jī)數(shù),其中RAND_MAX是stdlib.h中定義的一個(gè)整數(shù),它與系統(tǒng)有關(guān)。C語(yǔ)言中還有一個(gè)random - 函數(shù)可以獲取隨機(jī)數(shù),但是random - 不是標(biāo)準(zhǔn)函數(shù),不能在VC/VS等編譯器通過(guò),所以比較少用。
生成數(shù)字
- 1生成隨機(jī)數(shù)比較簡(jiǎn)單,=rand - 即可生成0-RAND_MAX之間的隨機(jī)數(shù); - #define RAND_MAX 0x7fffu
- 2如果要是整數(shù),就用=int - rand - %10,表示0至9的整數(shù),以此類(lèi)推;
- 3如果要生成a與b之間的隨機(jī)實(shí)數(shù),就用=rand - % - b-a+a,就能產(chǎn)生固定位數(shù)的整數(shù)了,以此類(lèi)推。
注意:如果要使用函數(shù)rand - 生成一隨機(jī)數(shù),并且使之不隨單元格計(jì)算而改變,可以在編輯欄中輸入“=rand - ”,保持編輯狀態(tài),然后按F9,將公式永久性地改為隨機(jī)數(shù)。
不過(guò),這樣只能一個(gè)一個(gè)的永久性更改,如果數(shù)字比較多,也可以全部選擇之后,另外選擇一個(gè)合適的位置粘貼,粘貼的方法是點(diǎn)擊右鍵,選擇“選擇性粘貼”,然后選擇“數(shù)值”,即可將之前復(fù)制的隨機(jī)數(shù)公式產(chǎn)生的數(shù)值(而不是公式)復(fù)制下來(lái)。
在實(shí)際編程中,我們經(jīng)常需要生成隨機(jī)數(shù),例如,貪吃蛇游戲中在隨機(jī)的位置出現(xiàn)食物,撲克牌游戲中隨機(jī)發(fā)牌。
字母
隨機(jī)小寫(xiě)字母:=CHAR - INT - RAND - *26+97
隨機(jī)大寫(xiě)字母:=CHAR - INT - RAND - *26+65
隨機(jī)大小寫(xiě)混合字母:=CHAR - INT - RAND - *26+if - INT - RAND - *2=0,65,97
有些情形下,我們需要生成一個(gè)不重復(fù)的隨機(jī)序列。
比如:我們要模擬洗牌,將一副撲克牌去掉大小怪后剩下的52張打亂。
比較笨的方法是在1-52間每生成一個(gè)隨機(jī)數(shù)后,檢查該隨機(jī)數(shù)是否出現(xiàn)過(guò),如果是第一次出現(xiàn),就放到序列里,否則重新生成一個(gè)隨機(jī)數(shù)作檢查。在excel worksheet里面用這種辦法,會(huì)造成if多層嵌套,不勝其煩,在VBA里面做簡(jiǎn)單一些,但是效率太差,越到序列的后端,效率越差。
當(dāng)然也有比較好的辦法,在VBA里面,將a - 1-a - 52分別賦予1-52,然后做52次循環(huán),例如,第s次生成一個(gè)1-52間的隨機(jī)數(shù)r,將a - s與a - r互換,這樣的話(huà),就打亂了原有序列,得到一個(gè)不重復(fù)的隨機(jī)序列。
VBA里這個(gè)算法是很容易實(shí)現(xiàn)的,但是,出于通用性和安全考慮,有的時(shí)候我們并不希望用VBA,我們來(lái)看看在worksheet里面如何利用內(nèi)置函數(shù)實(shí)現(xiàn)這個(gè)功能。
- 1在A(yíng)1-A52間填入"=INT - RAND - *52+1",產(chǎn)生1-52間的隨機(jī)數(shù),注意這里是有重復(fù)的。
- 2在B1-B52間填入1-52。
- 3在C54-BB54填入1-52。
- 4在C1填入"=IF - ROW - =C$54,INDEX - B$1:B$52,INDEX - $A$1:$A$52,C$54,IF - ROW - =INDEX - $A$1:$A$52,C$54,INDEX - B$1:B$52,C$54,B1"。
- 5將C1復(fù)制到C1:BA52這個(gè)區(qū)域里面。
- 6在BA1:BA52中,我們就得到了一個(gè)不重復(fù)的隨機(jī)序列,按F9可以生成一個(gè)新序列。
隨機(jī)產(chǎn)生六位數(shù)字密碼=INT - RAND - * - 899999-10001+100001。
EXCEL生成前2位是大寫(xiě)字母,中間4位是小寫(xiě)字母,后兩位是數(shù)字。
=CHAR - 65+INT - RAND - *16&CHAR - 65+INT - RAND - *16&CHAR - 97+INT - RAND - *16&CHAR - 97+INT - RAND - *16&CHAR - 97+INT - RAND - *16&CHAR - 97+INT - RAND - *16&INT - RAND - *10&INT - RAND - *10。
在A(yíng)1中輸入公式=rand - *100000,表示隨機(jī)數(shù)乘以一個(gè)比較大的數(shù),然后往下填充N(xiāo)個(gè)單元格。在B1中輸入排序公式=rank - A1,A:A,雙擊填充,或往下填充N(xiāo)個(gè)單元格,B1到BN就是你所需要的N個(gè)不同隨機(jī)數(shù)了。
解釋
rand()函數(shù)沒(méi)有輸入?yún)?shù),直接通過(guò)表達(dá)式rand()來(lái)引用;例如可以用下面的語(yǔ)句來(lái)打印兩個(gè)隨機(jī)數(shù):printf - "Random numbers are:%i%i/",rand - ,rand - 。
因?yàn)閞and()函數(shù)是按指定的順序來(lái)產(chǎn)生整數(shù),因此每次執(zhí)行上面的語(yǔ)句都打印相同的兩個(gè)值,所以說(shuō)C語(yǔ)言的隨機(jī)并不是真正意義上的隨機(jī)。
為了使程序在每次執(zhí)行時(shí)都能生成一個(gè)新序列的隨機(jī)值,我們通常通過(guò)為隨機(jī)數(shù)生成器提供一粒新的隨機(jī)種子。函數(shù)srand - - 來(lái)自stdlib.h可以為隨機(jī)數(shù)生成器播散種子。只要種子不同rand - 函數(shù)就會(huì)產(chǎn)生不同的隨機(jī)數(shù)序列。srand - 稱(chēng)為隨機(jī)數(shù)生成器的初始化器。
例程
當(dāng)提供的種子相同時(shí),隨機(jī)數(shù)序列也時(shí)相同的。而且當(dāng)種子為1時(shí),與不使用srand - 函數(shù)時(shí)一樣的,也就是說(shuō)rand - 函數(shù)默認(rèn)情況下初始化種子值為1。
在stdlib.h中這兩個(gè)函數(shù)的原型是:
int rand - ;
void srand - unsigned int;
srand - time - 0;i=rand - ;這樣i就是一個(gè)真正意義上的隨機(jī)數(shù)。
原因
rand - 產(chǎn)生偽隨機(jī)數(shù),srand函數(shù)提供種子,種子不同產(chǎn)生的隨機(jī)數(shù)序列也不同,所以通常先調(diào)用srand函數(shù)time - 0返回的是系統(tǒng)的時(shí)間(從1970.1.1午夜算起),單位:秒,種子不同當(dāng)然產(chǎn)生的隨機(jī)數(shù)相同幾率就很小了。
