發一個隨機紅包 100塊錢給10個人 每個人最多12塊錢 最少6塊錢 怎麼分
阿新 • • 發佈:2019-01-08
在微博上看到segmentfault上的一個題目,看了下問題,我自己想的就是先把每個人都分6元,然後在隨機分配剩下的40元.看了下原題的答案,已經有這樣的思路.哈哈.寫下我的程式碼.
有兩種做法:一種是從$leave裡面隨機 0 ~ ($max - $min)之間的數(可以是浮點數),然後隨機使用者的陣列,抽取一個,判斷兩者相加是否大於$max,如果大於,跳過;小於的話就把相加的結果賦值給該使用者.
另一種做法是先隨機抽取一個使用者,在根據使用者對比$max的差值隨機一個數,再相加給該使用者.我用的是這種.
/**
* $n = 10; // 人數
* $money = 100; // 錢總和
* $min = 6; // 下限6
* $max = 12; // 上線 12;
*/
function sendHongbao($money=100, $n=10, $min=6, $max=12){
$arr = array_fill( 0, $n, $min); // 填充每個人的錢的陣列
$leave = $money - $n * $min; // 還剩餘多少錢
// 隨機發放開始
while ($leave) {
// 隨機使用者
$lucky = array_rand($arr, 1);
if ($arr[$lucky] < $max){
// 判斷隨機數的上限
$randNum = mt_rand(1, ((($max - $arr[$lucky]) < $leave) ? ($max - $arr[$lucky]) : $leave ) );
$arr[$lucky] += $randNum;
$leave = $leave - $randNum;
}
}
return $arr;
}
理論上每個人的隨機獲取的錢是接近10的.所以測試方法是不是正確,先把程式碼跑100萬次,看看每個人的結果是不是接近於10.
寫個簡單的測試程式碼如下:
$sum = array(0,0,0,0,0,0,0,0,0,0);
for ($i=0; $i<1000000; $i++){
$res = sendHongbao();
$sum[0] += $res[0];
$sum[1] += $res[1];
$sum[2] += $res[2];
$sum[3] += $res[3];
$sum[4] += $res[4];
$sum[5] += $res[5];
$sum[6] += $res[6];
$sum[7] += $res[7];
$sum[8] += $res[8];
$sum[9] += $res[9];
}
echo "<pre>";
print_r($sum);
echo "</pre>";
結果如下:
Array
(
[0] => 9995735
[1] => 9998061
[2] => 9973085
[3] => 10001552
[4] => 9998657
[5] => 10002408
[6] => 9999013
[7] => 9998440
[8] => 10006077
[9] => 10026972
)
效率不高是個問題.如果有好的方法歡迎交流.