首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 產生不重複隨機數字的兩種演算法與效能比較

     編輯:PHP 相關知識

前言

在抽獎、驗證碼、隨機抽樣等情境下,常需要從指定範圍取出不重複的隨機數字。本文介紹兩種常見做法:陣列打亂法與迴圈檢查法,並實測其記憶體與執行時間表現。

方法一:陣列打亂法

建立 1 到 N 的陣列,用 shuffle() 打亂後取前 k 個。

function createRandID_shuffle($max, $count = 11) {
    $arr = range(1, $max);
    shuffle($arr);
    return implode(',', array_slice($arr, 0, $count));
}

優點:程式碼簡潔、保證不重複。
缺點:需建立完整陣列,記憶體消耗隨 $max 線性增長。當 $max = 900,000 時,已觸發 Allowed memory size exhausted 錯誤。

方法二:迴圈檢查法

用 while 迴圈產生隨機數,以 in_array() 檢查是否重複,直到集齊所需數量。

function createRandID_loop($max, $count = 11) {
    $arr = [];
    while (count($arr) < $count) {
        $num = rand(1, $max);
        if (!in_array($num, $arr)) {
            $arr[] = $num;
        }
    }
    return implode(',', $arr);
}

優點:記憶體固定(僅存結果陣列),不受 $max 影響。
缺點:當 $count 接近 $max 時,碰撞機率極高,效能急劇下降;但 $count 較小時極快。

實測數據(取 11 個數字)

範圍方法耗時(秒)記憶體
700,000shuffle0.67約 28 MB
700,000loop0.00016< 1 MB
999,999shuffleOOM超出 128 MB
999,999loop0.00014< 1 MB

進階優化:PHP 7.1+ 可用 array_rand()

function createRandID_modern($max, $count = 11) {
    $keys = array_rand(array_flip(range(1, $max)), $count);
    sort($keys);
    return implode(',', $keys);
}

註:array_flip(range(...)) 仍會建立大陣列,記憶體問題未解。若 $max 極大,建議改用 Reservoir Sampling 或資料庫 ORDER BY RAND() LIMIT k。

選擇建議

  • 小範圍(< 100,000)且需大量數字:shuffle 或 array_rand 最簡潔。
  • 大範圍(> 100,000)且只需少量數字:迴圈檢查法 最省記憶體且極快。
  • 極大範圍(百萬以上)且需大量數字:考慮資料庫隨機查詢或演算法優化(如 Fisher-Yates 部分打亂)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved