简单的PHP递归测试失败

时间:2009-12-27 14:20:37

标签: php recursion

我正在尝试基于递归数组的值创建多维数组的基本递归。

递归的工作原理是检查一个值,我们称之为“recursion”来启动循环并查找另一个值,我们将其称为“stop_recursion”结束。

基本上采用这个数组

array('One', 'Two', 'recursion', 'Three', 'Four', 'Five', 'stop_recursion', 'Six', 'Seven')

制作这个数组

array('One', 'Two', array('Three', 'Four', 'Five'), 'Six', 'Seven')

到目前为止我的代码如下

function testRecrusion($array, $child = false)
{
    $return = array();

    foreach ($array as $key => $value) {
        if ($value == 'recursion') {
            unset($array[$key]);
            $new = testRecrusion($array, true);
            $array = $new['array'];
            $return[] = $new['return'];
        } else {
            if ($value == 'stop_recursion') {
                unset($array[$key]);
                if ($child) {
                    return array('return' => $return, 'array' => $array);
                }
            } else {
                unset($array[$key]);
                $return[] = $value;
            }
        }
    }

    return $return;
}

但是那个输出是

Array
(
    [0] => One
    [1] => Two
    [2] => Array
        (
            [0] => Three
            [1] => Four
            [2] => Five
        )

    [3] => Three
    [4] => Four
    [5] => Five
    [6] => Six
    [7] => Seven
)

我想真正的问题是......数组值会不断循环遍历初始调用给出的第一个值,或者一旦返回新数组并设置它将循环通过该新数组。我知道答案基本上就在这里说是的,它会继续使用旧的数组值,但不应该这样做反之亦然吗?

任何帮助将不胜感激:)

------------编辑-------------------

我还可以补充一点,虽然我可以使用更简单的方法执行此操作,但需要对其进行递归检查,因为这将被移植到可能具有无限数量的子数组的字符串解析器。

5 个答案:

答案 0 :(得分:0)

您在上面的代码中遇到的问题是您正确检测何时应该递归调用此函数但是一旦它完成运行并将结果附加到输出数组,您只需选择下一个元素(这是递归调用的第一个元素)将得到)并将其附加到输出数组。您可能想要做的是当您检测到应该递归运行您的函数时,您应该跳过所有其他字符,直到找到停用词(stop_recursion)。显然,如果允许多级递归,问题会变得更难,那么你甚至可能需要跳过一些停用词,因为它们可能来自不同级别的调用。

我仍然不知道你为什么要这样的功能。也许你会解释你想要实现的目标。我很确定还有另一种更简单的方法。

答案 1 :(得分:0)

我建议你先从摆弄这条线开始,而不是帮忙完成这项工作:

foreach ($array as $key => $value) {

你应该传入你的数组,并检查是否在数组的末尾,因为它不能真正无限,知道你何时完成。

答案 2 :(得分:0)

当你在递归内部返回时,你需要返回内部数组和索引,从中继续搜索元素,这样你就不会两次查看同一个元素。试试这个:

function testRecursionImpl($array, $i)
{
    $return = array();

    for (; $i < sizeof($array); ++$i) {
        if ($array[$i] == 'recursion') {
            $new = testRecursionImpl($array, $i + 1);
            $return[] = $new[0];
            $i = $new[1];
        } else if ($array[$i] == 'stop_recursion') {
            return array($return, $i);
        } else {
            $return[] = $array[$i];
        }
    }

    return array($return, $i);
}

function testRecursion($array)
{
    $result = testRecursionImpl($array, 0);
    return $result[0];
}

答案 3 :(得分:0)

让我试一试

function testRecursion($arr){
    $return = array();
    $recurlevel = 0;
    foreach ($arr as $v) {
      if($v == 'stop_recursion'){
        $recurlevel--;
      }
      if($recurlevel == 0){
        if(isset($current)){
          $return[] = testRecursion($current);
          unset($current);
        }else{
          if($v != 'recursion'){
            $return[] = $v;
          }
        }
      }else{
        if(!isset($current)){
           $current = array();
        }
        $current[] = $v;
      }
      if($v == 'recursion'){
        $recurlevel++;
      }
    }

    return $return;
}

好的很好。即使递归和stop_recursion嵌套在另一个中,这也会有所帮助。见例:

code.php:

<pre><?php

function testRecursion($arr){
    $return = array();
    $recurlevel = 0;
    foreach ($arr as $v) {
      if($v == 'stop_recursion'){
        $recurlevel--;
      }
      if($recurlevel == 0){
        if(isset($current)){
          $return[] = testRecursion($current);
          unset($current);
        }else{
        if($v != 'recursion'){
          $return[] = $v;
        }
        }
      }else{
        if(!isset($current)){
           $current = array();
        }
          $current[] = $v;
      }
      if($v == 'recursion'){
        $recurlevel++;
      }
    }

    return $return;
}

$a = array('One', 'Two', 'recursion', 'Three', 'recursion', 'Four' , 'stop_recursion', 'Five', 'stop_recursion', 'Six', 'Seven');
var_dump(testRecursion($a));

?>

浏览器输出:

array(5) {
  [0]=>
  string(3) "One"
  [1]=>
  string(3) "Two"
  [2]=>
  array(3) {
    [0]=>
    string(5) "Three"
    [1]=>
    array(1) {
      [0]=>
      string(4) "Four"
    }
    [2]=>
    string(4) "Five"
  }
  [3]=>
  string(3) "Six"
  [4]=>
  string(5) "Seven"
}

答案 4 :(得分:0)

由于您已经回答了递归解决方案的问题......我可以提供基于堆栈的解决方案吗?

$x = array('a', 'b', 'recursion', 'cI', 'cII', 'cIII', 'recursion', 'cIV1', 'cIV2', 'cIV2', 'stop_recursion', 'stop_recursion', 'd', 'e');

$result = array();
$stack = array(&$result);
foreach($x as $e) {
  if ( 'recursion'===$e ) {
    array_unshift($stack, array());
    $stack[1][] = &$stack[0];
  }
  else if ( 'stop_recursion'===$e ) {
    array_shift($stack);
  }
  else {
    $stack[0][] = $e;
  }
}

var_dump($result);

打印

array(5) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  array(4) {
    [0]=>
    string(2) "cI"
    [1]=>
    string(3) "cII"
    [2]=>
    string(4) "cIII"
    [3]=>
    array(3) {
      [0]=>
      string(4) "cIV1"
      [1]=>
      string(4) "cIV2"
      [2]=>
      string(4) "cIV2"
    }
  }
  [3]=>
  string(3) "d"
  [4]=>
  string(5) "e"
}