Heim > Backend-Entwicklung > PHP-Tutorial > 自己写了一个红包生成算法 可以正确生成 缺无法递归出来?

自己写了一个红包生成算法 可以正确生成 缺无法递归出来?

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
Freigeben: 2016-07-06 13:52:36
Original
908 Leute haben es durchsucht

由于要生成随机红包,并且需要设置要发放红包的 金额、最小值、最大值、以及数量。

我尝试了 用for循环,但是会卡在 do while 这里, 所以用递归写了一个,内存中可以生成正确的红包,但是无法递归出来。请大牛帮忙看下问题 出在哪里?

<code><?php //调试函数
function p($arr)
{
    echo "<pre class="brush:php;toolbar:false">" . print_r($arr, true) . "</code>
Nach dem Login kopieren
Nach dem Login kopieren
"; } //发红包函数 function hongbao($money, $min, $max, $num, $arr = array(), $first = 'yes') { if ($first == 'yes') { //由于红包是以分为单位所以先转换单位,1元=100分,但只需转换一次 $money = $money * 100; $min = $min * 100; $max = $max * 100; //红包发放最大最小值合法性检测,防止发送死循环 if ($money - $min * $num 0) { return "你发放红包的金额太大 这些人领不完"; } } } //计算已生成的红包总额 $safe_total = array_sum($arr); //如果红包总额 大于或等于 要发放的总额, 就说明红包已经生成完毕 if ($safe_total >= $money) { //防止出现 最后出现的数据都相同,所以让这里随机排序一下 shuffle($arr); /*这里有异常, 可以打印出来正确的值 却无法return到最外面吧,应该是递归上的问题*/ p($arr); return $arr; } else { //随机生成红包金额 $rand = mt_rand($min, $max); //用当前的钱 减去已发的钱 -减去本次要发的钱 $zx = $money - $safe_total - $rand - ($num - 1) * $min; $zd = $money - $safe_total - $rand - ($num - 1) * $max; if ($zx >= 0 && $zd

回复内容:

由于要生成随机红包,并且需要设置要发放红包的 金额、最小值、最大值、以及数量。

我尝试了 用for循环,但是会卡在 do while 这里, 所以用递归写了一个,内存中可以生成正确的红包,但是无法递归出来。请大牛帮忙看下问题 出在哪里?

<code><?php //调试函数
function p($arr)
{
    echo "<pre class="brush:php;toolbar:false">" . print_r($arr, true) . "</code>
Nach dem Login kopieren
Nach dem Login kopieren
"; } //发红包函数 function hongbao($money, $min, $max, $num, $arr = array(), $first = 'yes') { if ($first == 'yes') { //由于红包是以分为单位所以先转换单位,1元=100分,但只需转换一次 $money = $money * 100; $min = $min * 100; $max = $max * 100; //红包发放最大最小值合法性检测,防止发送死循环 if ($money - $min * $num 0) { return "你发放红包的金额太大 这些人领不完"; } } } //计算已生成的红包总额 $safe_total = array_sum($arr); //如果红包总额 大于或等于 要发放的总额, 就说明红包已经生成完毕 if ($safe_total >= $money) { //防止出现 最后出现的数据都相同,所以让这里随机排序一下 shuffle($arr); /*这里有异常, 可以打印出来正确的值 却无法return到最外面吧,应该是递归上的问题*/ p($arr); return $arr; } else { //随机生成红包金额 $rand = mt_rand($min, $max); //用当前的钱 减去已发的钱 -减去本次要发的钱 $zx = $money - $safe_total - $rand - ($num - 1) * $min; $zd = $money - $safe_total - $rand - ($num - 1) * $max; if ($zx >= 0 && $zd

我按照你给的改的:

<?php
//调试函数
function p($arr)
{
    echo "<pre class="brush:php;toolbar:false">" . print_r($arr, true) . "
Nach dem Login kopieren
"; } //发红包函数 function luckymoney($money, $min, $max, $num, $arr = array(), $first = 'yes') { if ($first == 'yes') { //由于红包是以分为单位所以先转换单位,1元=100分,但只需转换一次 $money = $money * 100; $min = $min * 100; $max = $max * 100; //红包发放最大最小值合法性检测,防止发送死循环 if ($money - $min * $num < 0) { return "你发放红包的金额太小不足以 发给这么多人"; } else { if ($money - $max * $num > 0) { return "你发放红包的金额太大 这些人领不完"; } } } //计算已生成的红包总额 $safe_total = array_sum($arr); //如果红包总额 大于或等于 要发放的总额, 就说明红包已经生成完毕 if ($num == 1) { // if ($safe_total >= $money) { //防止出现 最后出现的数据都相同,所以让这里随机排序一下 $arr[] = $money - $safe_total; shuffle($arr); /*这里有异常, 可以打印出来正确的值 却无法return到最外面吧,应该是递归上的问题*/ // p($arr); return $arr; } else { //随机生成红包金额 $rand = mt_rand($min, $max); //用当前的钱 减去已发的钱 -减去本次要发的钱 $zx = $money - $safe_total - $rand - ($num - 1) * $min; $zd = $money - $safe_total - $rand - ($num - 1) * $max; if ($zx >= 0 && $zd <= 0) { //说明条件可以执行 $num--; $arr[] = $rand; // $xrr = $arr; return luckymoney($money, $min, $max, $num, $arr, 'no'); } else { //说明发完本次红包就没法继续下次了 所以不做修改。 // luckymoney($money, $min, $max, $num, $arr, 'no'); return luckymoney($money, $min, $max, $num, $arr, 'no'); // p($arr); // $arr[] = $rand; // shuffle($arr); // return $arr; } } } //发80块钱的红包, 最小1.3元 最大2, 数量为50个 //$myarr = luckymoney(5, 1.3, 2, 3); $myarr = luckymoney(80, 1.3, 2, 50); //打印下 myarr 看下赋值是否正确 , 函数里已经打印过一次, 所以要出现打印两次 数组才是正常 p($myarr); $array_sum = array_sum($myarr); p($array_sum);

注意由于你用的是递归, 而且是按照运气的随机很容易堆栈溢出,

我测试了一下你的数据luckymoney(80, 1.3, 2, 50) 5次大概成功2次,建议你改算法.....

return hongbao($money, $min, $max, $num, $arr, 'no');

谢谢大家,我重新用 for循环改进了一下算法。
按发 200元 最小1.3 最大3 发200个红包来计算

用for循环算法 ,函数执行100次 平均每次 执行时间为 0.004秒
用递归算法,函数执行100次,平均每次执行时间为 0.211秒

效率相差 52.75倍 上代码 谢谢@aristotll 给的建议

下面是 for循环代码,如果大家有更好的思路 请指导我一下,谢谢

&lt;?php
//调试函数
function p($arr)
{
    echo &quot;&lt;pre class=&quot;brush:php;toolbar:false&quot;&gt;&quot; . print_r($arr, true) . &quot;</pre><div class="contentsignin">Nach dem Login kopieren</div></div>";
}
//发红包函数
function hongbao($money, $min, $max, $num)
{
    
    $arr = array();
    //由于红包是以分为单位所以先转换单位,1元=100分,但只需转换一次
    $money = $money * 100;
    $min = $min * 100;
    $max = $max * 100;
    //红包发放最大最小值合法性检测,防止发送死循环
    if ($money - $min * $num < 0) {
        return "你发放红包的金额太小不足以 发给这么多人";
    } else {
        if ($money - $max * $num > 0) {
            return "你发放红包的金额太大 这些人领不完";
        }
    }
    $tempnum = $num;
    for ($i = 0; $i < $tempnum; $i++) {
        $flag = 'no';
        do {
            //随机生成一个红包
            $rand = mt_rand($min, $max);
            $anum = count($arr);
            $zx = $money - array_sum($arr) - $rand - ($num - 1) * $min;
            $zd = $money - array_sum($arr) - $rand - ($num - 1) * $max;
            $all = array_sum($arr);
            if ($zx >= 0 && $zd <= 0) {
                $arr[] = $rand;
                $flag = 'yes';
                $num--;
                
            } 
        } while ($flag == 'no');
    }
    shuffle($arr);
  
    return $arr;
}

$myarr = hongbao(200, 1, 3, 100);

p($myarr);
echo array_sum($myarr)/100;
Verwandte Etiketten:
php
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Aktuelle Ausgaben
PHP-Datenerfassung?
Aus 1970-01-01 08:00:00
0
0
0
PHP-Erweiterung intl
Aus 1970-01-01 08:00:00
0
0
0
Wie man PHP gut lernt
Aus 1970-01-01 08:00:00
0
0
0
Mehrere PHP-Versionen
Aus 1970-01-01 08:00:00
0
0
0
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage