搶紅包算法經常在面試的時候被問到,那么今天我就給大家分享一個比較常用容易理解的算法,線段分割法的實現。
算法思路:
線段分割法就是把紅包總金額想象成一條線段,而每個人搶到的金額,則是這條主線段所拆分出的子線段。
當N個人一起搶紅包的時候,就需要確定N-1個切割點。
因此,當N個人一起搶總金額為M的紅包時,我們需要做N-1次隨機運算,以此確定N-1個切割點。
隨機的范圍區間是(1, M)。當所有切割點確定以后,子線段的長度也隨之確定。這樣每個人來搶紅包的時候,只需要順次領取與子線段長度等價的紅包金額即可。
需要注意:
1、每個人最低也要搶到1分錢,要保證不能搶到0元的情況;
php代碼實現:
<?php
$num = 4; //紅包個數
$money = 100; //紅包錢數100元
$money_fen = $money * 100; //元轉換成分
//從1至總金額*100中,隨機取4-1個隨機數
$i = 1;
$rand = [];
while ($i < $num)
{
//$money_fen需要減1 不然最后一個人可能搶到0元
$rand_num = mt_rand(1,$money_fen-1);
//如果已經存在該隨機數不保存,主要解決搶到0元的情況
if(!in_array($rand_num,$rand,true))
{
$rand[] = $rand_num;
$i+=1;
}
}
//從小到大排序
sort($rand);
//中獎結果
$result = [];
foreach ($rand as $key =>$value)
{
if($key == 0)
{
$result[] = $value;
}
else
{
$result[] = $value - $rand[$key - 1];
}
}
//最后一個人的中獎結果
$result[] = $money_fen - $rand[count($rand) - 1];
//轉化成元
foreach ($result as $key=>$value)
{
$result[$key] = $value / 100;
}
print_r($result);