Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中的递归函数,用于查找任意节点之间的路径_Php_Recursion - Fatal编程技术网

PHP中的递归函数,用于查找任意节点之间的路径

PHP中的递归函数,用于查找任意节点之间的路径,php,recursion,Php,Recursion,我有一个表示节点之间连接的数组 给定一个特定的结束节点,我想返回指向该结束节点的节点子集 例如,如果我的节点定义为“a-b”、“a-c”、“c-E”、“E-f”、“E-k”、“k-z”、“q-z”、“x-q”、“k-m”、“c-t”,则表示以下内容: 我想看到通向“z”的路径,它们是: a-c,c-e,e-k,k-z q-z,x-q 我有以下PHP代码: <?php $end = "z"; $items = array("a-b", "a-c", "c-e", "e-f"

我有一个表示节点之间连接的数组

给定一个特定的结束节点,我想返回指向该结束节点的节点子集

例如,如果我的节点定义为“a-b”、“a-c”、“c-E”、“E-f”、“E-k”、“k-z”、“q-z”、“x-q”、“k-m”、“c-t”,则表示以下内容:

我想看到通向“z”的路径,它们是:

  • a-c,c-e,e-k,k-z
  • q-z,x-q

我有以下PHP代码:

<?php

$end   = "z";  
$items = array("a-b", "a-c", "c-e", "e-f", "e-k", "k-z", "q-z", "x-q", "k-m", "c-t"); 

$graph = getPre($items, $end);  

print_r($graph);  // This is what I want to populate

exit();

function getPre($array, $char) {  

  $predecessors = array_filter($array, function($line) use($char) {
      return strpos(substr($line, 2, 1), $char) === FALSE ? FALSE : TRUE;
            }
          );
  if (count($predecessors) == 0) {
    return;
  } else {
      print_r($predecessors)."<br>";
    echo "<br>";
    foreach ($predecessors as $pre) {getPre($array, substr($pre, 0,1));}
  }
}

?>
这至少是正确的节点列表,所以我就快到了

问题:如何在我的
$graph
数组中返回结果

在某个地方我需要
返回$preventors并将其与以前的结果合并。我还想添加能够指定开始节点的功能,但我认为这只是我的递归结束测试中的一个额外测试。

您需要的主要事情(如您所说)是构建数组以传回数据。如果有更多的元素要添加,则此代码将生成一个子元素;如果没有找到任何元素,则只为该项设置返回值。不确定输出的格式是否正是您想要的,但您可以使用它

function getPre($array, $char) {
    $graph = [];
    foreach ($array as $pre) {
        if ( $pre[2] == $char ) {
            $graph[$pre] = getPre($array, $pre[0]) ?: $pre;
        }
    }

    return $graph;
}
注意:不必使用
substr()
来提取字符,您可以将字符串用作数组,
[2]
是第三个字符

这将输出

Array
(
    [k-z] => Array
        (
            [e-k] => Array
                (
                    [c-e] => Array
                        (
                            [a-c] => a-c
                        )

                )

        )

    [q-z] => Array
        (
            [x-q] => x-q
        )

)
a-c,c-e,e-k,k-z
x-q,q-z
为了将代码输出为字符串,我使用迭代器处理了上述函数的结果。其思想是从叶节点开始,然后(使用
getSubIterator()
)追溯到树的底部

$graph = getPre($items, $end);
$objects = new RecursiveIteratorIterator( new RecursiveArrayIterator( $graph ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $objects as $name => $object )    {
    $path = $object;
    for ( $depth = $objects->getDepth() - 1; $depth >= 0; $depth-- ) {
        $path .= ",".$objects->getSubIterator( $depth )->key();
    }
    echo $path.PHP_EOL;
}
哪个输出

Array
(
    [k-z] => Array
        (
            [e-k] => Array
                (
                    [c-e] => Array
                        (
                            [a-c] => a-c
                        )

                )

        )

    [q-z] => Array
        (
            [x-q] => x-q
        )

)
a-c,c-e,e-k,k-z
x-q,q-z
您需要(正如您所说)的主要事情是构建阵列以将数据传回。如果有更多的元素要添加,则此代码将生成一个子元素;如果没有找到任何元素,则只为该项设置返回值。不确定输出的格式是否正是您想要的,但您可以使用它

function getPre($array, $char) {
    $graph = [];
    foreach ($array as $pre) {
        if ( $pre[2] == $char ) {
            $graph[$pre] = getPre($array, $pre[0]) ?: $pre;
        }
    }

    return $graph;
}
注意:不必使用
substr()
来提取字符,您可以将字符串用作数组,
[2]
是第三个字符

这将输出

Array
(
    [k-z] => Array
        (
            [e-k] => Array
                (
                    [c-e] => Array
                        (
                            [a-c] => a-c
                        )

                )

        )

    [q-z] => Array
        (
            [x-q] => x-q
        )

)
a-c,c-e,e-k,k-z
x-q,q-z
为了将代码输出为字符串,我使用迭代器处理了上述函数的结果。其思想是从叶节点开始,然后(使用
getSubIterator()
)追溯到树的底部

$graph = getPre($items, $end);
$objects = new RecursiveIteratorIterator( new RecursiveArrayIterator( $graph ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $objects as $name => $object )    {
    $path = $object;
    for ( $depth = $objects->getDepth() - 1; $depth >= 0; $depth-- ) {
        $path .= ",".$objects->getSubIterator( $depth )->key();
    }
    echo $path.PHP_EOL;
}
哪个输出

Array
(
    [k-z] => Array
        (
            [e-k] => Array
                (
                    [c-e] => Array
                        (
                            [a-c] => a-c
                        )

                )

        )

    [q-z] => Array
        (
            [x-q] => x-q
        )

)
a-c,c-e,e-k,k-z
x-q,q-z

php对递归不是很友好,即使语法正确,也很可能达到内存限制fast@Nathanael这有点讽刺,gioven PHP代表什么。。。希望我只会下降到单位数的深度。@Nathanel,这完全是不真实的Ephp不是非常递归友好的,即使语法正确,也很可能会达到内存限制fast@Nathanael这有点讽刺,gioven PHP代表什么。。。希望我只会下降到一个数字的深度。@Nathanel,那完全是不真实的。我可以看到所有必要的节点都在那里——是否有任何方法可以在一个一维数组中获取所有节点?还是一种简单地迭代所有元素的方法?谢谢Nigel。我可以看到所有必要的节点都在那里——是否有任何方法可以在一个一维数组中获取所有节点?还是一种简单地迭代所有元素的方法?