最近面试,遇到一个问题;面试官问:给你10块,让你发20个随机红包如何实现;之前没有接触过,也没有思路,于是回来百度知,得出以下几种方法:
基础方法
保证每人至少能拿0.01元;剩下按照随机数分发;
当我们输入红包数量和总金额后,PHP会根据这两个值进行随机分配每个金额,保证每个人都能领取到一个红包,每个红包金额不等,就是要求红包金额要有差异,所有红包金额总额应该等于总金额。
/** 实现随机红包
* @param $total 红包总金额
* @param $num 红包个数
* @return array
*/
public function rand_section($total,$num)
{
$min = 0.01;//每个人最少能收到0.01元
$data = [];
for ($i = 1; $i < $num; $i++) {
$safe_total = ($total - ($num - $i) * $min) / ($num - $i);//随机安全上限
$money = mt_rand($min * 100, $safe_total * 100) / 100;
$total = $total - $money;
$data[$i] = $money;
}
$data[$num] = $total;
return $data;
}
红包金额在指定区间内
思路:先计算剩余金钱的平均值,根据剩余金额的平局值获取最大值或者最小值距离平均值之间的一个正太分布值(范围内的随机值);保证在最大值和最小值之间
/** 获取区间内随机红包(符合正态分布)
* @param $min 红包最小值
* @param $max 红包最大值
* @param $num 红包个数
* @param $total 红包金额
* @return array
*/
public function rand_section ($min,$max,$num,$total){
$data = array();
if ($min * $num > $total) {
return array();
}
if($max*$num < $total){
return array();
}
while ($num >= 1) {
$num--;
$kmix = max($min, $total - $num * $max);
$kmax = min($max, $total - $num * $min);
$kAvg = $total / ($num + 1);
//获取最大值和最小值的距离之间的最小值
$kDis = min($kAvg - $kmix, $kmax - $kAvg);
//获取0到1之间的随机数与距离最小值相乘得出浮动区间,这使得浮动区间不会超出范围
$r = ((float)(rand(1, 10000) / 10000) - 0.5) * $kDis * 2;
$k = sprintf("%.2f", $kAvg + $r);
$total -= $k;
$data[] = $k;
}
return $data;
}
好了,经过长时间的研究和努力终于算有所成就,如果该方法有什么不妥的地方可以及时指出,希望能帮助到各位;谢谢您的观看
参考文章关闭了,对不起参考作者,嘿嘿;也谢谢各位大神的参考文章,如果我找到作者的文章,一定会各位推荐