2014-04-30 54 views
2

我想在1000到9999之間生成2000個唯一的隨機數。 我正在做類似這樣的事情,但它不會生成唯一的數字。php 2000 1000到9999之間的唯一隨機數

$numbers = array();    

// Loop while there aren't enough numbers 
while (count($numbers) < 2000) { 

    $random_number = rand(1000, 9999); 

    if (!in_array($random_number, $numbers)) {    
     // This adds the number to the array  
     $numbers[] = 'A'.$random_number.'14'; 
    } 

} 

請大家幫忙。

+1

刪除數組中的所有數字,然後通過循環運行數組以檢查新滾動的數字是否已經存在。 – kpp

+0

@kpp我想你錯過了'in_array'部分。 – h2ooooooo

+2

您找到'1234',然後添加'A123414'。 –

回答

3

您檢查一些是否存在等,說4567,但你加'A456714',所以你不會找到號碼。

你能解決這個問題是這樣的:

$numbers = array();    

// Loop while there aren't enough numbers 
while (count($numbers) < 2000) { 

    $random_number = rand(1000, 9999); 

    $code = 'A'.$random_number.'14'; 

    if (!in_array($code, $numbers)) {    
     // This adds the number to the array  
     $numbers[] = $code; 
    } 

} 

我必須說,通過deceze的解決方案也很不錯(更好,其實)。不同的是,在他的解決方案中,你根本沒有任何雙重數字來檢查,所以在大多數情況下它可能會更快。

缺點是你將有一個9000數字相對較大的數組。對於這種特定的情況,他的解決方案甚至可能會更好,但如果您選擇較小數量的隨機數或更大的範圍,則(您自己的)解決方案可能會更好。如果你想從range(100, 1000000)中選擇100個隨機數,那麼這個解決方案可能會更好,因爲選擇一個雙數的機會非常小,檢查它是相當輕量級的。

很難判斷轉折點在哪裏,但對於你目前的情況,我會選擇他的。

+0

謝謝@GolezTrol這工作完美。 – user3588408

+0

該解決方案的下行是不可預測的執行時間(您無法真正知道生成這些2k數字需要多少時間),而Decease的解決方案具有線性執行時間。 –

+0

這是真的,我已經在回答中解決了這個問題。 – GolezTrol

12

而不是運行許多隨機嘗試,一個小範圍的,如這一點,我寧願用這個辦法:

$candidates = range(1000, 9999); 
shuffle($candidates); 
$numbers = array_slice($candidates, 0, 2000); 
$numbers = array_map(function ($number) { return "A{$number}14"; }, $numbers); 
+0

+1簡單而乾淨! – Deepsy

+0

這比僅僅循環播放if-statements遍佈整個地方的時間要好!太好了! – Naruto

+0

感謝解決方案@deceze的確非常簡單和乾淨。再次感謝。 – user3588408

1

而不是檢查的數量是否已經存在的數組,試試這個:

<?php 

$numbers=array(); 

while (count($numbers)<2000) 
{ 
    $numbers['A'.rand(1000,9999).'14']=true; 
} 

$unique=array_keys($numbers); 

echo print_r($unique,true).PHP_EOL; 

它使用的事實,數組鍵是唯一刪除陣列檢查。我猜想計算陣列中元素的數量要快得多

0

這是因爲您將A和14添加到要放入數組$ number中的每個數字中。 因此,每個數字的下一個循環產生有不會是任何相同數量有..

對不起,我蹩腳的英語..

0

random.org API:

$numbers = explode(PHP_EOL, 
    file_get_contents(
     'http://www.random.org/integers/?num=2000&min=1000&max=9999&col=1&base=10&format=plain&rnd=new' 
    ) 
); 


$numbers = array_map(function($v) { 
    return 'A' . $v . '14'; 
}, $numbers); 
+0

這種微不足道的問題的HTTP調用開銷...?在這裏,對隨機性的要求更好。 :P如果我不相信默認實現,我寧願實現基於'/ dev/random'的自己的'shuffle'。 – deceze

+1

有趣的是,獲取和解析結果已經比'腳本'實現中的代碼更多了,並且它引入了執行外部請求並且必須解析大結果字符串的開銷。當然,你會引入不必要的外部依賴。 – GolezTrol

+0

你對開銷都是正確的,我甚至不知道爲什麼我發佈了這個答案; -S我自己使用'/ dev/urandom'流。 – DanFromGermany

0
function random_in_rang($min, $max, $count) 
{ 
    $numbers = array(); 
    for($i=0; $i<$count; $i++) 
    { 
     //decrease range after adding a new random value 
     $rnd = rand($min, $max-$count); 
     //new value should be unique 
     while(isset($numbers[$rnd])) $rnd++; 
    } 
    return array_keys($numbers); 
} 
0

更EFFIC ient方式(對於速度和內存使用),用於大範圍:

function get_unique_random_numbers($min,$max,$count) { 
    $numbers = array(); 
    while(count($numbers) < $count) { 
      $numbers["A".mt_rand($min,$max)."14"] = 1; 
    } 
    return array_keys($numbers); 
} 

$numbers = get_unique_random_numbers(0,90000000,20000); 
// < 0.X seconds 

此方法是當($max-$min) >> $count更有效。 但($max-$min) ~ $count的速度很慢。 當($max-$min) < $count時,它會產生無限循環。

所以要小心。 :)最後在開始循環之前進行檢查。