2010-09-26 55 views
2

我需要幫助編寫一些代碼,它將從12個數字組成的數組中創建一個隨機數,然後在沒有模糊的情況下打印它9次。這對我來說很難完成。有任何想法嗎?在Javascript中沒有使用隨機數字生成器?

+2

你也可以贊成答案:) – 2010-09-27 05:33:38

回答

7
var nums = [1,2,3,4,5,6,7,8,9,10,11,12]; 
var gen_nums = []; 

function in_array(array, el) { 
    for(var i = 0 ; i < array.length; i++) 
     if(array[i] == el) return true; 
    return false; 
} 

function get_rand(array) { 
    var rand = array[Math.floor(Math.random()*array.length)]; 
    if(!in_array(gen_nums, rand)) { 
     gen_nums.push(rand); 
     return rand; 
    } 
    return get_rand(array); 
} 

for(var i = 0; i < 9; i++) { 
    document.write(get_rand(nums)); 
} 
0

如果我正確理解你,你想洗牌你的數組。

循環幾次(數組的長度應該這樣做),並且在每次迭代中,獲得兩個隨機數組索引並在那裏交換兩個元素。 (更新:如果你對此非常認真,這可能不是best algorithm)。

然後,您可以打印前九個數組元素,它們將以隨機順序排列,不再重複。

0

這樣做相對簡單,它背後的理論是創建另一個數組,用於跟蹤您使用的數組中的哪些元素。

var tempArray = new Array(12),i,r; 
for (i=0;i<9;i++) 
    { 
    r = Math.floor(Math.random()*12); // Get a random index 
    if (tempArray[r] === undefined)  // If the index hasn't been used yet 
     { 
     document.write(numberArray[r]); // Display it 
     tempArray[r] = true;    // Flag it as have been used 
     } 
    else         // Otherwise 
     { 
     i--;        // Try again 
     } 
    } 

其它方法包括洗牌陣列,從數組中取出使用的元件,或移動使用的元件的陣列的端部。

+0

儘管不要使用上面的代碼,但它是一個非常簡單的例子,用於演示你正在嘗試做的背後的邏輯(從12個值的數組中打印9個值以隨機順序)。 – 2010-09-26 06:40:25

+0

儘管它似乎產生了一個無偏差的數字序列。我能看到的唯一問題是性能,因爲越來越難找到剩餘的數字。 – Thilo 2010-09-26 07:02:43

+0

準確地說,雖然該算法對於較小的數據集足夠了,但對於較大的集合,您需要確保不會發生衝突,無論是通過從陣列中刪除數據還是將其推到最後。 – 2010-09-26 07:15:13

0

嘗試這一次,

//Here o is the array; 
var testArr = [6, 7, 12, 15, 17, 20, 21]; 
    shuffle = function(o){ //v1.0 
         for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); 
         return o; 
       }; 
shuffle(testArr); 
4

做到這一點的最有效和最有效的方法是洗你的號碼,然後打印他們的前九。使用good shuffle algorithm。Thilo建議的結果會給你帶來不好的結果。 See here.

編輯 這裏有一個簡短的Knuth的隨機算法例如:


void shuffle(vector<int> nums) 
{ 
    for (int i = nums.size()-1; i >= 0; i--) 
    { 
    // this line is really shorthand, but gets the point across, I hope. 
    swap(nums[i],nums[rand()%i]); 
    } 
} 
+0

如果你認真對待它,使用你所建議的經過驗證的算法看起來好像更好。我只想指出,我提出的算法並不是在「see here」中討論的算法。 – Thilo 2010-09-26 06:58:12

+0

這是不相同的算法,沒有。但是我擔心,如果我理解正確,它仍然會產生同樣的錯誤。你的算法會有n^3個結果落入n中!框。這不能給予均勻的分配。用你的算法嘗試文章中的實驗,看看它是否有效。 – JoshD 2010-09-26 07:06:07

+0

在對您鏈接的博客的評論中,「我的」算法由「fabio」提出。他聲稱它可以工作,但交換次數更多(不僅僅是數組大小)。我會再讀一遍,看看我能證明它是對還是錯。儘管它有性能問題,但Andrew Dunn的提議似乎在統計上也是正確的。 – Thilo 2010-09-26 07:20:06

0

這裏是獲得的最小值和最大值之間的隨機數沒有重複的通用方法:

function inArray(arr, el) { 
    for(var i = 0 ; i < arr.length; i++) 
      if(arr[i] == el) return true; 
    return false; 
} 

function getRandomIntNoDuplicates(min, max, DuplicateArr) { 
    var RandomInt = Math.floor(Math.random() * (max - min + 1)) + min; 
    if (DuplicateArr.length > (max-min)) return false; // break endless recursion 
    if(!inArray(DuplicateArr, RandomInt)) { 
     DuplicateArr.push(RandomInt); 
     return RandomInt; 
    } 
    return getRandomIntNoDuplicates(min, max, DuplicateArr); //recurse 
} 

通話用:

var duplicates =[]; 
for (var i = 1; i <= 6 ; i++) { 
    console.log(getRandomIntNoDuplicates(1,10,duplicates)); 
}