本篇內容介紹了“PHP紅包算法的思路分享”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
根據很多需求的使用場景,如發紅包、砍價類需求,這兩個功能都有一個同樣的特點,如下:
紅包
1.總金額
2.紅包個數
3.最小紅包數量
砍價
1.砍價總金額
2.需要多少人完成砍價(人數根據需求而定)
固定砍價人數
隨機砍價人數
指定隨機砍價人數
第2點三個規則都需要根據規則得出一個人數
3.最小砍價金額
開發思路
最小金額不允許小于0
總金額不允許大于數量乘最小金額
取得平均金額(總金額/剩余數量)
分配金額 平均金額小于等于最金額時直接分配最小金額
獲取金額幅度比例最小值不允許小于-1最大值不允許大于1
得出分配金額 幅度計算(平均值*(1+幅度比例))
分配金額判斷分配金額小于最小金額或者分配金額大于可領取最大金額((最小金額+剩余總金額)- (剩余數量×最小金額))時 重新分配金額
剩余最后一個則剩余所有金額都分配
開發代碼
<?php
/**
* 發送紅包
* Class sandRed
*/
class sandRed
{
#紅包金額
protected $amount;
#紅包個數
protected $num;
#領取的紅包最小金額
protected $minAmount;
#紅包分配結果
protected $amountArr = [];
public function __construct($amount, $num = 1, $minAmount = 1)
{
$this->amount = $amount;
$this->num = $num;
$this->minAmount = $minAmount;
}
/**
* 處理返回
* @return array
* @throws Exception
*/
public function handle()
{
# 驗證
if ($this->amount < $validAmount = $this->minAmount * $this->num) {
throw new Exception('紅包總金額必須≥'.$validAmount.'元');
}
# 分配紅包
$this->allot();
return $this->amountArr;
}
/**
* 分配紅包
*/
protected function allot()
{
# 剩余可分配的紅包個數
$num = $this->num;
# 剩余可領取的紅包金額
$amount = $this->amount;
while ($num >= 1) {
if ($num == 1) {
# 剩余一個的時候,直接取剩余紅包
$coupon_amount = $this->formattingAmount($amount);
} else {
# 平均金額
$avgAmount = $this->formattingAmount($amount / $num);
# 分配金額
$countAllotAmount = $this->countAllotAmount($avgAmount, $amount, $num);
# 剩余的紅包的平均金額
$coupon_amount = $this->formattingAmount($countAllotAmount);
}
# 追加分配金額
$this->amountArr[] = $coupon_amount;
# 計算剩余金額
$amount -= $coupon_amount;
$num--;
}
# 隨機打亂
// shuffle($this->amountArr);
}
/**
* 計算分配的紅包金額
* @param float $avgAmount 每次計算的平均金額
* @param float $amount 剩余可領取金額
* @param int $num 剩余可領取的紅包個數
* @return float
*/
protected function countAllotAmount($avgAmount, $amount, $num)
{
# 如果平均金額小于等于最低金額,則直接返回最低金額
if ($avgAmount <= $this->minAmount) {
return $this->minAmount;
}
# 浮動比率
$floatingRate = $this->floatingRate();
# 分配金額
$allotAmount = $avgAmount * (1 + $floatingRate);
# 浮動計算
$coupon_amount = $this->formattingAmount($allotAmount);
# 如果低于最低金額或超過可領取的最大金額,則重新獲取
if ($coupon_amount < $this->minAmount || $coupon_amount > $this->canReceiveMaxAmount($amount, $num)) {
return $this->countAllotAmount($avgAmount, $amount, $num);
}
return $coupon_amount;
}
/**
* 計算分配的紅包金額-可領取的最大金額
* @param $amount
* @param $num
* @return float|int
*/
protected function canReceiveMaxAmount($amount, $num)
{
return $this->minAmount + $amount - $num * $this->minAmount;
}
/**
* 紅包金額浮動比例
* @return float|int
*/
protected function floatingRate()
{
# 60%機率獲取剩余平均值的大幅度紅包(可能正數、可能負數)
if (rand(1, 100) <= 60) {
# 上下幅度70%
return rand(-70, 70) / 100;
}
# 其他情況,上下浮動30%;
return rand(-30, 30) / 100;
}
/**
* 格式化金額,保留2位
* @param $amount
* @return string
*/
protected function formattingAmount($amount)
{
return sprintf('%01.2f', round($amount, 2));
}
}總金額
$amount = 1;
分配數量
$num = 10;
最小金額
$minAmount = 0.01; $red = new sandRed($amount, $num, $minAmount); $res = $red->handle(); print_r($res);
輸出結果 [0.10,0.04,0.08,0.04,0.16,0.14,0.11,0.13,0.11,0.09]
echo array_sum($res);
輸出結果 1
“PHP紅包算法的思路分享”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。