# 闲来无事，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);

• 评论

• 上一篇
• 下一篇