假設有如下一個陣列 


  1. $list = array(“A” => 5, “B” => 10, “C” => 15, “D” => 20, “E” => 50); 

表示隨機ABCDE,取到A的概率是5%,B為10%,C為15%,D為20%,E為50%。

思路很簡單,畫一根數軸,長度是ABCDE的權值的總和,按照他們的權值,分割這個數軸。

然後隨機取數軸上的一點,落在哪個區間,就取哪個值。

9055836806934EBCB4272B12502AB86D

具體演算法如下


  1. function GetRandom() { 
  2.     $list = array(“A” => 5, “B” => 10, “C” => 15, “D” => 20, “E” => 50); 
  3.     $sum = 0; 
  4.     $listPoint = array(0);//這個陣列記錄了每個切割點的值,就是記錄了數軸上,5,15,30,50,100的值。 
  5.     foreach ($list as $key => $value) { 
  6.         $sum+=$value;//計算出權值的總和 
  7.         array_push($listPoint$sum);//把分割點放到陣列中 
  8.     } 
  9.     $num = rand(0, $sum);//取0到sum之間一個隨機值 
  10.     //echo $num . “:”; 
  11.     for ($i = 0; $i < count($listPoint) – 1; $i++) 
  12.     { 
  13.         if ($num >= $listPoint[$i] && $num <= $listPoint[$i + 1]) //判斷隨機值落在哪個範圍內 
  14.         { 
  15.             $elem = array_slice($list$i, 1); 
  16.             return key($elem); //第i項的值 
  17.         } 
  18.     } 
  19.     echo “can`t be here”

測試程式碼,隨機取100次,看看各個字母出現的次數。 


  1. $a = 0; 
  2. $b = 0; 
  3. $c = 0; 
  4. $d = 0; 
  5. $e = 0; 
  6. for ($i = 0; $i < 100; $i++) { 
  7.     $char = GetRandom(); 
  8.     echo “$char  “
  9.     switch ($char) { 
  10.         case “A”
  11.             $a++; 
  12.             break
  13.         case “B”
  14.             $b++; 
  15.             break
  16.         case “C”
  17.             $c++; 
  18.             break
  19.         case “D”
  20.             $d++; 
  21.             break
  22.         case “E”
  23.             $e++; 
  24.             break
  25.     } 
  26. echo “A:$a<br>”
  27. echo “B:$b<br>”
  28. echo “C:$c<br>”
  29. echo “D:$d<br>”
  30. echo “E:$e<br>”
  31. die(0); 

447B4E407350427492B79AC236BF90B6

得到的結果勉強也能接受。