Kongsi idea untuk melaksanakan algoritma sampul merah PHP (dengan kod pembangunan dilampirkan)

藏色散人
Lepaskan: 2023-04-10 16:28:01
ke hadapan
3775 orang telah melayarinya
根据很多需求的使用场景,如发红包、砍价类需求,这两个功能都有一个同样的特点,如下:
Salin selepas log masuk

Sampul merah

1 Jumlah amaun
2 🎜>3 .Bilangan minimum sampul merah

Perundingan

1 Jumlah amaun tawar-menawar

2 orang bergantung pada permintaan)

    Bilangan tetap orang untuk tawar-menawar
  • Bilangan rawak orang untuk tawar-menawar
  • Bilangan rawak orang yang ditentukan untuk tawar-menawar
  • Perkara 2: Ketiga-tiga peraturan itu semuanya memerlukan bilangan orang untuk ditentukan mengikut peraturan
3 Amaun tawar-menawar minimum

Idea pembangunan.

Parameter pengesahan

Jumlah minimum tidak dibenarkan kurang daripada 0
Jumlah jumlah tidak dibenarkan lebih besar daripada kuantiti didarab dengan jumlah minimum
Jumlah pengagihan

Dapatkan amaun purata (jumlah jumlah/kuantiti yang tinggal)

Jumlah pengagihan Jumlah purata
Apabila amaun maksimum Peruntukkan amaun minimum secara langsung 小于等于 Dapatkan amaun
Minimum nilai tidak dibenarkan kurang daripada 幅度比例 Nilai maksimum tidak dibenarkan lebih besar daripada -1 1 untuk mendapatkan jumlah pengagihan Pengiraan amplitud (purata * (1
)) 幅度比例Penghakiman jumlah pengagihan
kurang daripada 分配金额 atau 最小金额 lebih besar daripada 分配金额 ((jumlah baki jumlah minimum) - (baki kuantiti × jumlah minimum) Apabila jumlah itu diagihkan semula 可领取最大金额 jumlah baki yang terakhir akan menjadi semua amaun yang tinggal. Semua diperuntukkan

kod pembangunan

<?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(&#39;%01.2f&#39;, round($amount, 2));
    }
}
Salin selepas log masuk
    jumlah keseluruhan
$amount = 1;
Salin selepas log masuk
    kuantiti diperuntukkan
$num = 10;
Salin selepas log masuk
    Jumlah minimum
$minAmount = 0.01;

$red = new sandRed($amount, $num, $minAmount);

$res = $red->handle();
print_r($res);
Salin selepas log masuk
    Hasil keluaran [0.10,0.04,0.08,0.04,0.16,0.1 0.11,0.13,0.11, 0.09]
echo array_sum($res);
Salin selepas log masuk
    Hasil keluaran 1
Pembelajaran yang disyorkan: "

Tutorial Video PHP"

Atas ialah kandungan terperinci Kongsi idea untuk melaksanakan algoritma sampul merah PHP (dengan kod pembangunan dilampirkan). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
php
sumber:segmentfault.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!