PHP递归函数嵌套级别达到了

时间:2015-07-22 15:07:15

标签: php recursion

美好的一天。我有一个parcer函数,它接受一个像这样的字符串数组:

['str','str2','str2','*str','*str2','**str2','str','str2','str2']

并递归提升从asterix开始的级别以获得此

['str','str2','str2',['str','str2',['str2']],'str','str2','str2']

功能是:

function recursive_array_parser($ARRAY) {
    do {

        $i = 0;
        $s = null;
        $e = null;
        $err = false;

        foreach ($ARRAY as $item) {

            if (!is_array($item)) { //if element is not array
                $item = trim($item);
                if ($item[0] === '*' && $s == null && $e == null) { //we get it's start and end if it has asterix
                    $s = $i;
                    $e = $i;
                } elseif ($item[0] === '*' && $e != null)
                    $e = $i;
                elseif (!isset($ARRAY[$i + 1]) || $s != null && $e != null) { //if there are no elements or asterix element ended we elevate it
                    $e = $e == NULL ? $i : $e;
                    $head = array_slice($ARRAY, 0, $s);
                    $_x = [];
                    $inner = array_slice($ARRAY, $s, $e - $s + 1);
                    foreach ($inner as $_i)
                        $_x[] = substr($_i, 1);

                    $inner = [$_x];
                    $tail = array_slice($ARRAY, $e + 1, 999) or [];
                    $X = array_merge($head, $inner);
                    $ARRAY = array_merge($X, $tail);

                    $s = null;
                    $e = null;
                    $err = true;
                }
            } else {
                $ARRAY[$i] = recursive_array_parser($ARRAY[$i]); //if the item is array of items we recur.
            }
            $i++;

            if ($err == true) {
                break 1;
            }
        }
    } while ($err);
    return $ARRAY;
}

当此功能运行时,我得到"致命错误:' 200'的最大功能嵌套级别到达,流产!"错误。

我知道它与无限递归有关,但是我无法跟踪它发生的特定位置,这很奇怪。

2 个答案:

答案 0 :(得分:2)

我通常不会重写代码,但您可以减少和简化代码,同时从我所看到的,获得所需的结果。看看这是否适合你:

$a = array('a','b','c','*d','*e','**f','g','*h');
print_r($a);
$a = recursive_array_parser($a);
print_r($a);
function recursive_array_parser($array)
{
    $ret = array();
    for($i=0; $i<sizeof($array); $i++)
    {
        if($array[$i]{0}!='*') $ret[] = $array[$i];
        else
        {
            $tmp = array();
            for($j=$i; $j<sizeof($array) && $array[$j]{0}=='*'; $j++)
            {
                $tmp[] = substr($array[$j],1);
            }
            $ret[] = recursive_array_parser($tmp);
            $i = $j-1;
        }
    }
    return $ret;
}

请注意,$ array [$ i]不可能是一个数组,因此删除了检查。递归发生在找到*时创建的临时数组上。在解析了一系列*元素之后,$ i更接近于$ array以正确地重置它。

答案 1 :(得分:0)

这是我的解决方案。没有嵌套循环。

function recursive_array_parser($arr) {
    $out = array();
    $sub = null;
    foreach($arr as $item) {
        if($item[0] == '*') { // We've hit a special item!
            if(!is_array($sub)) { // We're not currently accumulating a sub-array, let's make one!
                $sub = array();
            }
            $sub[] = substr($item, 1); // Add it to the sub-array without the '*'
        } else {
            if(is_array($sub)) { 
                // Whoops, we have an active subarray, but this thing didn't start with '*'. End that sub-array
                $out[] = recursive_array_parser($sub);
                $sub = null;
            }
            // Take the item
            $out[] = $item;
        }
    }

    if(is_array($sub)) { // We ended in an active sub-array. Add it.
        $out[] = recursive_array_parser($sub);
        $sub = null;
    }

    return $out;
}