一个外包项目需要给用户发红包,本想看看有没有朋友开发过,直接复制一段代码的。但是看了网上很多都是封装的类。虽然写的都很棒,不过我觉得一个红包分配没必要搞那么复杂。因此仿照别人的代码实现了一个简易版的红包随机分配算法,支持普通红包和拼手气红包。
完整方法:
- /**
- * $total float 红包总额
- * $num integer 红包个数
- * $type string normal平分红包,其他值随机分配
- * $min float 最小红包金额
- */
- function cal_hongbao($total, $num = 1,$type='normal',$min = 0.01)
- {
- $money_arr = array();
- $return_arr = array();
- if($type == 'normal'){
- //普通红包
- $amount = bcdiv($total,$num,2);
- $money_arr = array_fill(0,$num,$amount);
- }else{
- //拼手气红包
- for ($i = 1; $i <$num; ++$i) {
- $max =round($total, 2)/($num-$i);
- $random = 0.01+ mt_rand() / mt_getrandmax() * (0.99- 0.01);
- $money = $random*$max;
- $money = $money<=$min?0.01:$money;
- $money =floor($money*100)/100;
- $total = $total - $money;
- $money_arr[$i] = round($money, 2);
- }
- $money_arr[$i] = round($total, 2);
- shuffle($money_arr);
- }
- $return_arr['money'] = $money_arr;
- $return_arr['total'] = array_sum($money_arr);
- return $return_arr;
- }
备注:
①普通红包可能会存在总金额不能均分的情况,这个时候大家可以自行处理,可以让用户修改发红包的金额,或者把多余部分随机给其中一人增加上去。这个需要自行处理。
测试方法就不写了。省点字。
2022/11/28更新方法,支持把总额分成随机小整数,需要自行判断红包总额大于总个数的问题。否则会以最小数填充数组。
- /**
- * $total float 红包总额
- * $num integer 红包个数
- * $type string normal平分红包,其他值随机分配
- * $min float 最小红包金额
- */
- function cal_hongbao($total, $num = 1,$type='normal',$min = 0.01)
- {
- $money_arr = array();
- $return_arr = array();
- if($type == 'normal'){
- //普通红包
- $amount = bcdiv($total,$num,2);
- $money_arr = array_fill(0,$num,$amount);
- }elseif ($type == 'fumi'){
- //福米红包,把总额分成N个小整数,总和=总额
- $can = $total-$num; //剩余可分配的数额
- for ($i=$num;$i>0;$i--){
- $money_arr[$i] = 1; //每个数字最小为1
- $ls_money = 0;
- if($can > 0){
- if($i == 1){
- $money_arr[$i] += $can;
- }else{
- $max_money = floor($can/$i);
- $ls_money = mt_rand(0,$max_money);
- $money_arr[$i] += $ls_money;
- }
- }
- $can -= $ls_money;
- }
- shuffle($money_arr);
- }else{
- //拼手气红包
- for ($i = 1; $i <$num; ++$i) {
- $max =round($total, 2)/($num-$i);
- $random = 0.01+ mt_rand() / mt_getrandmax() * (0.99- 0.01);
- $money = $random*$max;
- $money = $money<=$min?0.01:$money;
- $money =floor($money*100)/100;
- $total = $total - $money;
- $money_arr[$i] = round($money, 2);
- }
- $money_arr[$i] = round($total, 2);
- shuffle($money_arr);
- }
- $return_arr['money'] = $money_arr;
- $return_arr['total'] = array_sum($money_arr);
- return $return_arr;
- }