早上地铁里无聊,看到CSDN公众号推的一篇文章,是随机红包的实现,有兴趣的可以看原文,这里只做php版的代码实现
漫画:如何实现抢红包算法?
https://mp.weixin.qq.com/s/7yDbdKHJ3OmNw_015Jc8Cg
废话不多说,上代码:
class RedPackageService{ private static $instance; private function __construct() { } private function __clone() { // TODO: Implement __clone() method. } public static function getInstance() { if(!(self::$instance instanceof self)) self::$instance = new self; return self::$instance; } /**保证每个人拿到的概率相同(保证公平) * @param $total int 红包总金额,单位分 * @param $number int 参与抢红包的数量 * @return array * Array ( [0] => 22.05 单位元,精确到分 [1] => 9.15 [2] => 27.35 [3] => 12.84 [4] => 25.74 [5] => 0.94 [6] => 26.93 ) */ public function byAverage($total,$number) { $data = []; for($i=0;$i<$number;$i++) { if($number == ($i+1)) $data[] = round($total/100,2); else { $area = round($total / ($number - $i), 0) * 2; $re = random_int(1, $area); $data[] = round($re/100,2); $total -= $re; } } return $data; } /**保证红包金额随机性 * @param $total int 红包总金额 单位分 * @param $number int 参与人数 * @return array * Array ( [0] => 3.49 [1] => 7.83 [2] => 27.24 [3] => 4.53 [4] => 15.31 [5] => 32.61 [6] => 33.99 ) */ public function byRandom($total,$number) { $data = $divided_points = []; //获取随机分割点,在0-$total之间寻找$number-1个 for($i=0;$i<$number-1;$i++) { $tmp_point = random_int(1,$total-1); //检查分割点是否存在 while (in_array($tmp_point,$divided_points)) { $tmp_point = random_int(1,$total-1); } array_push($divided_points,$tmp_point); } //加入终止分割点 array_push($divided_points,$total); //分割点排序,从小到大,index会变动 asort($divided_points); //根据分割点获取随机金额 $a = 0; foreach ($divided_points as $b) { $data[] = round(($b-$a)/100,2); $a = $b; } // for($i=1;$i<$number;$i++) // $data[] = round(($divided_points[$i]-$divided_points[$i-1])/100,2); return $data; } }
测试执行代码
$re = RedPackageService::getInstance()->byRandom(12500,7); print_r($re);可能需要注意一下你的namespace
两个方法各有所长各有缩短,大家理性看待,随便玩玩,开心就好