PHP中的递归函数,用于查找任意节点之间的路径
我有一个表示节点之间连接的数组 给定一个特定的结束节点,我想返回指向该结束节点的节点子集 例如,如果我的节点定义为“a-b”、“a-c”、“c-E”、“E-f”、“E-k”、“k-z”、“q-z”、“x-q”、“k-m”、“c-t”,则表示以下内容: 我想看到通向“z”的路径,它们是: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-c,c-e,e-k,k-z
- q-z,x-q
<?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。我可以看到所有必要的节点都在那里——是否有任何方法可以在一个一维数组中获取所有节点?还是一种简单地迭代所有元素的方法?