当前位置: 首页 > 后端技术 > PHP

PHP红包算法_0

时间:2023-03-29 23:38:45 PHP

PHP红包算法用在很多场景,比如发红包,砍价需求。这两个函数有相同的特点,如下:红包1.总金额2.红包数量3.最少红包数议价1.议价总额2.需要多少人完成议价(人数视需求而定)。固定讨价还价的人数是随机的。随机议价的人数是指定的。议价金额开发思路验证参数最小金额不允许小于0总金额不允许大于数量乘以最小金额分配金额求平均金额(总金额/剩余金额)当分配金额的平均金额小于或等于最大金额,直接分配最小金额获取金额范围比例的最小值不允许小于-1,最大值不允许大于1获取分配量范围计算(平均值*(1+范围比))分配量判断分配量小于最小量或分配量大于最大量可收到((最小金额+剩余总金额)-(剩余金额×最小金额))重新分配金额和剩余最后一个,所有剩余金额nt将分配给开发代码amount=$amount;$this->num=$num;$this->minAmount=$minAmount;}/***handlereturns*@returnarray*@throwsException*/publicfunctionhandle(){#Validateif($this->amount<$validAmount=$this->minAmount*$this->num){thrownewException('红包总额必须≥'.$validAmount.'元');}#分配红包$this->allot();返回$this->amountArr;}/***分配红包*/protectedfunctionallot(){#剩余红包可分配个数$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);/***计算发放的红包数量*@paramfloat$avgAmount每次计算的平均数量*@paramfloat$amount剩余可领取数量*@paramint$num剩余红包数量可以领取*@returnfloat*/protectedfunctioncountAllotAmount($avgAmount,$amount,$num){#如果平均金额小于等于最小金额,则直接返回最小金额if($avgAmount<=$this->minAmount){返回$this->minAmount;}#浮动利率$floatingRate=$this->floatingRate();#分配金额$allotAmount=$avgAmount*(1+$floatingRate);#浮动计算$coupon_amount=$this->formattingAmount($allotAmount);#如果低于最低可领取金额或超过最高可领取金额,重新获取$this->countAllotAmount($avgAmount,$amount,$num);}返回$coupon_amount;}/***计算分配的红包数量-可领取的最大数量*@param$ammount*@param$num*@returnfloat|int*/protectedfunctioncanReceiveMaxAmount($amount,$num){返回$this->minAmount+$amount-$num*$this->minAmount;}/***红包金额浮动比例*@returnfloat|int*/protectedfunctionfloatingRate(){#60%几率获得剩余平均值的大红包(可能为正数或负数)if(rand(1,100)<=60){#上下70%returnrand(-70,70)/100;}#其他情况,上下30%;返回兰特(-30,30)/100;}/***格式化金额,保留2位*@param$amount*@returnstring*/protectedfunctionformattingAmount($amount){returnsprintf('%01.2f',round($amount,2));}}总金额$amount=1;分配金额$num=10;最低金额$minAmount=0.01;$red=newsandRed($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]echoarray_sum($res);输出结果1