洗牌算法是將有序序列隨機打亂的經典問題。本文介紹基於 費雪-耶茨演算法 的 PHP 實作,時間複雜度 O(n),空間複雜度 O(n),是實現公平洗牌、隨機排序的標準做法。
<?php
/**
* 簡單洗牌算法 - 費雪-耶茨演算法
* @param int $card_num 牌數/陣列長度
* @return array 打亂後的索引陣列
*/
function wash_card($card_num) {
$cards = $tmp = [];
// 初始化有序陣列
for ($i = 0; $i < $card_num; $i++) {
$tmp[$i] = $i;
}
// 核心洗牌邏輯
for ($i = 0; $i < $card_num; $i++) {
$index = rand(0, $card_num - $i - 1);
$cards[$i] = $tmp[$index];
unset($tmp[$index]);
$tmp = array_values($tmp); // 重新索引
}
return $cards;
}
// 測試:54 張撲克牌洗牌
print_r(wash_card(54));
?>
費雪-耶茨演算法(Fisher-Yates Shuffle)的核心思想:
實際專案中,推薦直接使用 PHP 內建的 shuffle() 或 array_rand():
$cards = range(0, 53);
shuffle($cards); // 原地打亂,O(n) 時間複雜度
// 或取隨機鍵值
$random_keys = array_rand($cards, 5);
shuffle() 內部同樣採用費雪-耶茨演算法,效能經 C 層優化,比用戶空間實作更快。
範例中使用 rand(),PHP 7.1+ 起 rand() 已為 mt_rand() 別名。若需加密級隨機性(如博彩系統),請改用 random_int()。另請留意 array_values() 在大陣列中會有效能開銷,實際專案可優化為指標交換方式。