2011-08-12 41 views
2

好吧,所以我需要在1-10之間創建四個隨機生成的數字,它們不能相同。所以我的想法是將每個數字添加到數組中,但是如何檢查數字是否在數組中,如果是,重新生成數字,如果它不是將新數字添加到數組中?Javascript每次生成隨機唯一編號

所以基本上它會去,

1,創建新的號碼,並添加到陣列 2.創建第二個新號,查,看它是否已經存在,如果不存在,添加到陣列。如果確實存在,重新創建新號碼,再次檢查等等。 3.與上面一樣等等。

+0

哪些步驟遇到問題? –

+0

你已經知道該怎麼做了。所有你需要做的就是試試看。如果不知何故,它不工作發佈你的代碼在這裏讓人們看和幫助你。 –

回答

9

你想要什麼叫'隨機抓包'。考慮一下你有一個「袋子」的數字,每個數字只在這個袋子裏代表一次。你隨機抽出數字,儘可能多的。

這裏提出的一些其他解決方案的問題是,他們隨機生成數字,並檢查它是否已被使用。這將需要更長和更長的時間來完成(理論上達到無限的時間),因爲你正在等待random()函數返回一個你還沒有的值(並且沒有來做到這一點,它可以永遠給你1-9,但永遠不會返回10)。

有很多方法來實現一個抓包類型的解決方案,每個解決方案都有不同程度的成本(但是,如果做得正確,將永遠不會是無限的)。

最基本的問題的解決方案將是如下:

var grabBag = [1,2,3,4,5,6,7,8,9,10]; 

// randomize order of elements with a sort function that randomly returns -1/0/1 
grabBag.sort(function(xx,yy){ return Math.floor(Math.random() * 3) - 1; }) 

function getNextRandom(){ 
    return grabBag.shift(); 
}; 

var originalLength = grabBag.length; 
for(var i = 0; i < originalLength .length; i++){ 
    console.log(getNextRandom()); 
} 

這當然是破壞原有grabBag陣列。我不確定這種「真正的隨機」是如何,但對於許多應用來說,它可能是「足夠好」的。

稍微不同的方法是將所有未使用的元素存儲在數組中,隨機選擇一個索引,然後刪除該索引處的元素。這裏的成本是每次刪除元素時你創建/銷燬數組的頻率。

+0

從剩餘選擇池中刪除所選項目絕對是一種方法。任何需要測試唯一性的算法都會有非常糟糕的最壞情況執行時間。 – Tom

2

使用數組來查看數字是否已經生成。

var randomArr = [], trackingArr = [], 
    targetCount = 4, currentCount = 0, 
    min = 1, max = 10, 
    rnd; 

while (currentCount < targetCount) { 
    rnd = Math.floor(Math.random() * (max - min + 1)) + min; 
    if (!trackingArr[rnd]) { 
     trackingArr[rnd] = rnd; 
     randomArr[currentCount] = rnd; 
     currentCount += 1; 
    } 
} 

alert(randomArr); // Will contain four unique, random numbers between 1 and 10. 

工作例如:http://jsfiddle.net/FishBasketGordo/J4Ly7/

+0

這可能永遠不會完成,特別是如果N很大,並且您選擇的M個單位接近N.請參閱我在@ Joseph的回答中的評論。 – Matt

+0

非常真實。我贊成你的答案。 – FishBasketGordo

1
var a = []; 
for (var i = 0; i < 5; i++) { 
    var r = Math.floor(Math.random()*10) + 1; 
    if(!(r in a)) 
    a.push(r); 
    else 
    i--; 
} 

這會爲你做它。不過要小心。如果你使生成的隨機數的數量大於可能的數字(10),你將會遇到一個無限循環。

+0

+1但是爲什麼聲明'errors'並且從不使用它? – Paulpro

+0

@PaulPRO lol在修正bug時使用它,但決定使用nix該功能:P(將會增加錯誤並稍後顯示) –

+0

這可能需要很長時間才能完成,具體取決於您需要多少個數字以及您有多幸運是。它在理論上每次都會返回1,並且你的循環永遠不會終止。現在,實際上,這不可能發生在您擁有的數據上。但是,如果你有很多數字,並且你需要這些數字的很大一部分,那麼可能需要很長時間才能完成。 – Matt

2

下面是使用馬特的grabBag技術幾個版本:

function getRandoms(numPicks) { 
    var nums = [1,2,3,4,5,6,7,8,9,10]; 
    var selections = []; 

    // randomly pick one from the array 
    for (var i = 0; i < numPicks; i++) { 
     var index = Math.floor(Math.random() * nums.length); 
     selections.push(nums[index]); 
     nums.splice(index, 1); 
    } 
    return(selections); 
} 

你可以看到它在這裏工作:http://jsfiddle.net/jfriend00/b3MF3/

而且,這裏可以讓你在你想覆蓋的範圍內傳遞一個版本:

function getRandoms(numPicks, low, high) { 
    var len = high - low + 1; 
    var nums = new Array(len); 
    var selections = [], i; 
    // initialize the array 
    for (i = 0; i < len; i++) { 
     nums[i] = i + low; 
    } 

    // randomly pick one from the array 
    for (var i = 0; i < numPicks; i++) { 
     var index = Math.floor(Math.random() * nums.length); 
     selections.push(nums[index]); 
     nums.splice(index, 1); 
    } 
    return(selections); 
} 

而且一搗鼓一個:http://jsfiddle.net/jfriend00/UXnGB/

0

我使用遞歸函數。測試功能選擇6到1和9之間的唯一值。

//test(1, 9, 6); 

function test(min, max, nbValue){ 
    var result = recursValue(min, max, nbValue, []); 
    alert(result); 
} 

function recursValue(min, max, nbValue, result){ 
    var randomNum = Math.random() * (max-min); 
    randomNum = Math.round(randomNum) + min; 

    if(!in_array(randomNum, result)){ 
     result.push(randomNum); 
     nbValue--; 
    } 

    if(nbValue>0){ 
     recursValue(min, max, nbValue, result); 
    } 
    return result; 
} 

function in_array(value, my_array){ 
    for(var i=0;i< my_array.length; i++){ 
     if(my_array[i] == value){ 
      console.log(my_array+" val "+value); 
      return true; 
     }   
    } 
    return false; 
} 
0

這是一個遞歸函數,您在尋找什麼。

"howMany" parameter is count of how many unique numbers you want to generate. 
"randomize" parameter is biggest number that function can generate. 

例如:蘭特(4,8)函數返回一個其中有4號陣列,並且數字是0到7(因爲大家知道,的Math.random()函數生成的數字開始之間從零到[給定數字-1])

var array = []; 
var isMatch= false; 
function rand(howMany, randomize){ 
    if(array.length < howMany){ 
    var r = Math.floor(Math.random() * randomize); 
    for(var i = 0; i < howMany; i++){ 
     if(array[i] !== r){ 
      isMatch= false; 
      continue; 
      } else { 
      isMatch= true; 
      break; 
     } 
    } 
    if(isMatch == false){ 
     array.push(r); 
      ran(howMany, randomize); 
    } 
     ran(howMany, randomize); 
    return array; 
    } 
}