闲来无事,PHP撸两个红包算法
早上地铁里无聊,看到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
两个方法各有所长各有缩短,大家理性看待,随便玩玩,开心就好
还没有评论,来说两句吧...