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

PHP 高效生成不重複隨機數:mt_rand + 翻翻法優化方案

     編輯:PHP 綜合知識

場景痛點

需從 1~25 中隨機抽取 16 個不重複數字,且要填補 200 筆缺失投票記錄。普通 array_unique 去重效率低,本文介紹「翻翻法」優化方案。

核心函數實現

<?php
/**
 * 生成指定範圍、指定數量的不重複隨機數
 * @param int $min 最小值
 * @param int $max 最大值
 * @param int $num 需要數量
 * @return array 隨機數陣列(鍵名連續 0~n-1)
 */
function unique_rand($min, $max, $num) {
    $return = array();
    while (count($return) < $num) {
        $return[] = mt_rand($min, $max);
        // 翻翻法去重:利用鍵值互換特性,比 array_unique 快數倍
        $return = array_flip(array_flip($return));
    }
    // 打亂並重置鍵名,保證 0~n-1 連續
    shuffle($return);
    return array_values($return);
}

// 使用示例
$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
?>

關鍵優化點解析

1. mt_rand() 替代 rand()

Mersenne Twister 算法,速度快 4 倍,隨機質量更高,適合大量生成場景。

2. 「翻翻法」去重原理

$arr = [2, 5, 2, 8];
$flipped = array_flip($arr);    // [2 => 0, 5 => 1, 8 => 3] 鍵值互換,重複值被覆蓋
$unique = array_flip($flipped); // [2, 5, 8] 再次互換回原值

利用陣列鍵名唯一性,兩次 array_flip 即可完成去重,效能遠優於 array_unique。

3. shuffle() + array_values() 重置鍵名

去重後鍵名可能不連續(如 [0 => 2, 2 => 5, 4 => 8]),shuffle 打亂順序並重新索引,配合 array_values 保證輸出為標準連續索引陣列,便於後續 foreach 遍歷。

進階場景:大範圍大數量優化

若範圍極大(如 1~1000000 取 500000),上述方法會因碰撞導致循環次數暴增。改用 範圍洗牌法:

function unique_rand_large($min, $max, $num) {
    $range = range($min, $max);      // 建立完整範圍
    shuffle($range);                 // 全量打亂
    return array_slice($range, 0, $num); // 截取前 N 個
}

時間複雜度 O(N),記憶體佔用 O(N),適合範圍不超過百萬級場景。

總結建議

場景推薦方法複雜度
小範圍、小數量(<10000)mt_rand + 翻翻法O(k) 期望
大範圍、大數量(>10000)range + shuffle + sliceO(N)
極大範圍、極少數量隨機集合 + 布隆過濾器O(k) 空間換時間

根據業務數據規模選擇最優策略,避免過度優化或性能瓶頸。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved