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

PHP 產生指定數量不重複隨機數的高效能寫法

     編輯:PHP 相關知識

PHP 產生指定數量不重複隨機數的高效能寫法

需求:從 1~25 中隨機抽取 16 個不重複數字(模擬投票場景)。以下提供高效能解法並解析關鍵技巧。

核心函式

/**
 * 產生不重複隨機整數陣列
 * @param int $min  最小值(含)
 * @param int $max  最大值(含)
 * @param int $num  需要數量
 * @return array    索引連續的整數陣列
 */
function unique_rand(int $min, int $max, int $num): array {
    if ($num > ($max - $min + 1)) {
        throw new InvalidArgumentException("請求數量超過範圍");
    }
    $result = [];
    while (count($result) < $num) {
        $result[] = mt_rand($min, $max);
        // 「翻翻法」去重:利用鍵值互換特性,比 array_unique() 快數倍
        $result = array_flip(array_flip($result));
    }
    shuffle($result); // 打亂順序並重置鍵名為 0~n-1
    return $result;
}

// 使用範例
$arr = unique_rand(1, 25, 16);
sort($arr); // 如需排序
echo implode(',', $arr);
// 輸出範例:2,3,4,6,7,8,9,10,11,12,13,16,20,21,22,24

關鍵技巧解析

技巧說明效能優勢
mt_rand()梅森旋轉演算法,速度約 rand() 4 倍,隨機品質更好高
翻翻法 array_flip(array_flip($arr))利用陣列鍵名唯一性去重,避免 array_unique() 內部排序開銷極高(大陣列下可快 10x+)
shuffle()打亂順序並重建連續數字鍵,避免去重後鍵名斷裂導致遍歷麻煩必要步驟

替代方案:範圍較小時

// 當範圍不大(如 1~1000),建立完整陣列洗牌切片更快
function unique_rand_small_range(int $min, int $max, int $num): array {
    $pool = range($min, $max);
    shuffle($pool);
    return array_slice($pool, 0, $num);
}

應用場景延伸

  • 抽獎系統:獎池 ID 不重複抽取
  • 問卷隨機選題:題庫中抽取指定數量
  • 資料採樣:從大量資料中隨機取樣
  • 遊戲發牌:洗牌後發牌

注意事項

  1. PHP 7.1+ mt_rand() 已修正偏差問題,可放心使用。
  2. 極大範圍(如 1~1億)且需少量數字時,翻翻法最佳;需大量數字時,range() 會佔用大量記憶體,改用集合(如 SplFixedArray)或資料庫 ORDER BY RAND() LIMIT n。
  3. 加密用途請改用 random_int()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved