加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_开封站长网 (http://www.0378zz.com/)- 科技、AI行业应用、媒体智能、低代码、办公协同!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

详解实现PHP红包算法的思路

发布时间:2022-08-03 16:05:56 所属栏目:PHP教程 来源:互联网
导读:红包 1.总金额 2.红包个数 3.最小红包数量 砍价 1.砍价总金额 2.需要多少人完成砍价(人数根据需求而定) 固定砍价人数 随机砍价人数 指定随机砍价人数 第2点三个规则都需要根据规则得出一个人数 3.最小砍价金额 开发思路 验证参数 最小金额不允许小于0 总金
  红包
 
  1.总金额
  2.红包个数
  3.最小红包数量
 
  砍价
 
  1.砍价总金额
  2.需要多少人完成砍价(人数根据需求而定)
 
  固定砍价人数
  随机砍价人数
  指定随机砍价人数
  第2点三个规则都需要根据规则得出一个人数
  3.最小砍价金额
 
  开发思路
 
  验证参数
  最小金额不允许小于0
  总金额不允许大于数量乘最小金额
  分配金额
 
  分配金额 平均金额小于等于最金额时直接分配最小金额
  获取金额幅度比例 最小值不允许小于 -1 最大值不允许大于 1
  得出分配金额 幅度计算(平均值*(1+幅度比例))
  分配金额判断 分配金额小于最小金额或者分配金额大于 可领取最大金额 ((最小金额+剩余总金额)- (剩余数量×最小金额))时 重新分配金额
  剩余最后一个则剩余所有金额都分配
  开发代码
 
 
   * 发送红包
 
   * 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;
 
 
       * 处理返回
 
       * @return array
 
       * @throws Exception
 
       */
 
      public function handle()
 
      {
 
          # 验证
 
          if ($this->amount < $validAmount = $this->minAmount * $this->num) {
 
              throw new Exception('红包总金额必须≥'.$validAmount.'元');
 
          }
 
          # 分配红包
 
          $this->allot();
 
          return $this->amountArr;
 
          # 剩余可分配的红包个数
 
          $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;
 
 
   
 
      /**
 
       * 计算分配的红包金额
 
       * @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%;
 
 
      /**
 
       * 格式化金额,保留2位
 
       * @param $amount
 
       * @return string
 
       */
 
      protected function formattingAmount($amount)
 
      {
 
          return sprintf('%01.2f', round($amount, 2));
 
      }
 
  }
 
  总金额
 
  $amount = 1;
 
  分配数量
 
  $num = 10;
 
  最小金额
 
 
   
 
  $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

(编辑:开发网_开封站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读