【问题标题】:PHP - Nest a for loop a variable number of timesPHP - 嵌套一个for循环可变次数
【发布时间】:2014-05-20 03:24:45
【问题描述】:

我是 PHP(以及一般编程)的初学者。 为了测试我到目前为止所学的内容,我编写了这段代码,它打印了一组骰子与一定数量的面的所有可能组合。 (你会在最后找到代码)。

我想要做的是根据$dicenumber 变量动态改变嵌套for循环的数量。现在它只能处理 3 个骰子,因为代码是:

            for ($d1=1; $d1 <= $d1value ; $d1++) { 
                for ($d2=1; $d2 <= $d2value ; $d2++) { 
                for ($d3=1; $d3 <= $d3value ; $d3++) { 
                        array_push(${sum.($d1+$d2+$d3)}, "$d1"."$d2"."$d3");
                    }
                }
            }

但我想改变它,例如,如果 $dicenumber2,它会产生类似:

            for ($d1=1; $d1 <= $d1value ; $d1++) { 
                for ($d2=1; $d2 <= $d2value ; $d2++) { 
                        array_push(${sum.($d1+$d2)}, "$d1"."$d2");
                }
            }

我希望代码可以处理$dicenumber 的任何数字,没有限制。环顾四周,似乎我必须添加某种递归代码,但我不知道该怎么做。有小费吗?此外,任何关于我做错了什么的反馈都会非常有帮助!谢谢!

            <?php
            //defines the number and type of dice
            $dicenumber = 3;
            $dtype = 6;
            //defines the maximum value of every die 
            for ($i=1; $i <=$dicenumber ; $i++) { 
                ${d.$i.value} = $dtype;
            }
            //defines and array for each possible sum resulting from the roll of the given number of dice. 
            for ($i=$dicenumber; $i <= ($dtype*$dicenumber) ; $i++) { 
            ${sum.$i} = array();
            }

            //the troublesome piece of code I want to change    

            for ($d1=1; $d1 <= $d1value ; $d1++) { 
                for ($d2=1; $d2 <= $d2value ; $d2++) { 
                for ($d3=1; $d3 <= $d3value ; $d3++) { 
                        array_push(${sum.($d1+$d2+$d3)}, "$d1"."$d2"."$d3");
                    }
                }
            }

            //prints all the possible roll combinations, each line lists combination that share the same sum
            for ($i=$dicenumber; $i <= ($dtype*$dicenumber); $i++) { 
        print join(" ", ${sum.$i})."<br />";
        }
        ?>

【问题讨论】:

    标签: php for-loop nested-loops


    【解决方案1】:

    这里我们有一个两个功能的过程。第一个函数buildArrays 以正确的格式创建数组以输入第二个函数allCombinations。因此,对于这个使用 3 个 d6 的示例,buildArrays 将生成一个与此等效的数组:

    $data = array(
        array(1, 2, 3, 4, 5, 6),
        array(1, 2, 3, 4, 5, 6),
        array(1, 2, 3, 4, 5, 6));
    

    我会警告你,当你增加骰子的数量和面数时,可能的组合数量会成倍增加!这意味着您可以对服务器提出非常大的需求,并且超时和最大内存限制将很快发挥作用。生成的数组可能非常非常大,并且很快消耗超过最大内存限制。也就是说,我们开始吧:

    function buildArrays($dicenumber, $dtype){
    
        for ($i = 0; $i<$dicenumber; $i++){
            $tmp = array();
            for ($j = 1; $j<=$dtype; $j++){
                $tmp[] = $j;
            }
            $data[$i] = $tmp;
        }
        return $data;
    }
    
    
    
    function allCombinations($data){
    
        $result = array(array()); //this is crucial, dark magic.
    
        foreach ($data as $key => $array) {
            $new_result = array();
            foreach ($result as $old_element){
                foreach ($array as $element){
                    if ($key == 0){
                        $new_result[] = $element;
                    } else {
                        $new_result[] = $old_element.$element;
                    }
                }
            $result = $new_result;
            }
        }
        return $result;
    }
    
    //set variables
    $dicenumber = 3;
    $dtype = 6;
    
    //set_time_limit(0); //You may need to uncomment this for large values.
    
    //call functions
    $data = buildArrays($dicenumber, $dtype);
    $results = allCombinations($data);
    
    //print out the results
    foreach ($results as $result){
        echo $result."<br/>";   
    }
    

    注意这个答案是the cartesian product code的变体

    【讨论】:

    • 非常感谢!!你不知道这对我来说有多大的信息量。我看到这段代码一个接一个地打印出组合,而我原来的不稳定代码将它们打印成按总和排序的行。您的过程显然更加灵活,因为我可以以任何我喜欢的方式操作输出,包括将它们按行排序,这是我接下来要做的事情:)再次感谢!真的很感激。
    【解决方案2】:

    如果你学过函数,你可以进行递归调用并跟踪你在哪个 dicenumber 上,然后在每次调用函数时递增它(并在你点击 # 后结束循环)。 understanding basic recursion

    【讨论】:

    • 感谢您的回复。我有一些用户制作功能的概念(即我在 CodeCademy 中做了那个单元),过去几个小时我一直在摆弄它,但我被困住了,因为我找不到添加它的方法array_push(${sum.($d1+$d2+$d3)}, "$d1"."$d2"."$d3");动态进入递归函数...有什么建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2022-11-18
    • 2018-07-24
    • 1970-01-01
    相关资源
    最近更新 更多