- 摩刻部落 - https://www.moke.tw/wordpress -

JavaScript小程式:不重覆的random亂數

JavaScript所提供的 Math.random() 亂數函數只會產生0-1之間的數值,若要取得A-B之間的亂數則要經過運算(很多程式都是如此)。網路上隨便搜尋就可以找到解決的公式。不過,有時候我們需要產生不止一個亂數,而需要產生 n 個不重覆的亂數,這樣的話該怎麼辦呢?本系列提供作者行自撰寫常用的 JavaScript函數,方便有需要的人直接取用。

取得A-B之間的亂數

function getRandom(minNum, maxNum) {	//取得 minNum(最小值) ~ maxNum(最大值) 之間的亂數
	return Math.floor( Math.random() * (maxNum - minNum + 1) ) + minNum;
}

這是網路上常見的公式。Math.random()是JavaScript內建函數,會(以時間為種子)亂數產生一個 0 ~ 1 之間的數值。maxNum - minNum + 1 可以計算出亂數的範圍大小(例如:0 ~ 20 共有 21 個數值)。兩者相乘之後使用 Math.floor() 去除小數點,最後再加上 minNum 基數(最小值 minNum 不一定為 0,例如當 minNum = 5 時,亂數產生的 0 應該調整為 5)。

產生不重覆的亂數

function getRandomArray(minNum, maxNum, n) {	//隨機產生不重覆的n個數字
	var rdmArray = [n];		//儲存產生的陣列

	for(var i=0; i

若要產生不重覆的亂數,就必須在亂數產生後檢查該亂數是否出現過。因為要產生好幾個亂數,所以第 2 行宣告一個陣列來儲存,接著第 4 行使用一個 for 迴圈依序產生亂數。第 7 ~ 14 行會不斷地產生亂數,直到產生出陣列裡沒有的亂數為止。第 8 行使用一個 flag 記錄此次產生的亂數是否已存在,預設值為 false。第 9 行產生亂數之後(配合上面的function),第 12 行利用 indexOf() 搜尋此亂數是否存在於陣列中,有找到 indexOf() 會回傳陣列的位置,找不到則回傳 -1。如果此亂數存在於陣列中,exist = true 會導致 14 行的 while(是否繼續執行回圈) 成立,因此回到第 7 行重新執行迴圈,反之則離開迴圈,將此亂數存到陣列中(16行)。當 n 個不重覆的亂數都產生之後,離開 for 迴圈,並且回傳陣列(18行)。

有興趣練習演算法的人可以試試進階一點的寫法。第 2 行宣告陣列時不指定陣列的大小(即:var rdmArray = [];),第 4 行改成 while() 迴圈,一直執行迴圈直到陣列大小 >= n 為止。使用陣列的 push() 函數將亂數加入陣列中。如此一來便可以做出相同的效果。