您好,欢迎访问一九零五行业门户网

分享实现PHP红包算法的思路(附开发代码)

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视频教程》
以上就是分享实现php红包算法的思路(附开发代码)的详细内容。
其它类似信息

推荐信息