PHP在多维数组中查找路径
Posted
技术标签:
【中文标题】PHP在多维数组中查找路径【英文标题】:PHP Find path in multidimensional array 【发布时间】:2018-08-26 08:06:16 【问题描述】:假设我们有一个数组,其中包含许多定义特定节点路径的数组。例如:
X1 X3 X5
| | |
A -- B -- C -- D
| | |
X2 X4 X6
还有代码:
$array = [
'A' => ['B','X1','X2'],
'B' => ['C','X3','X4'],
'C' => ['D','X5','X6'],
];
用最多 2 个节点找到从一个点到另一个点的路径的最佳方法是什么?例如,要从 A 到 D,您需要从 A 到 B 到 C 再到 D。
现在我已经编写了一个执行此搜索的函数,但我确信有更好的方法来执行此搜索(可能是递归的)。
private function findpath($array, $start, $end)
$result = array();
foreach ($array[$start] as $key1 => $value1)
foreach ($array[$value1] as $key2 => $value2)
if (in_array($end, $array[$value2]))
return $result = [$start, $value1, $value2, $end];
findpath($array, 'A', 'D');
// returns
// array:4 [
// 0 => "A"
// 1 => "B"
// 2 => "C"
// 3 => "D"
// ]
【问题讨论】:
【参考方案1】:一种可能的方法是使用堆栈作为要检查的路径列表。在一个循环中,您可以从堆栈中删除一条路径,检查它是否找到目标,如果没有,则通过在节点的$array
中查找下一步来生成新路径,然后将新路径添加到堆栈中由循环的下一次迭代检查。如果堆栈为空,则意味着找不到从开始到结束的路径。
您提供的原始$array
不允许路径循环或重复,但出于测试目的,我扩展了您的数组,假设所有节点都完全连接:
$array = [
'A' => ['B','X1','X2'],
'B' => ['A', 'C','X3','X4'],
'C' => ['B', 'D','X5','X6'],
'D' => ['C'],
'X1' => ['A'],
'X2' => ['A'],
'X3' => ['B'],
'X4' => ['B'],
'X5' => ['C'],
'X6' => ['C'],
];
鉴于此,维护一个单独的已访问节点列表也是一个好主意,这样代码就不会重新访问节点或陷入循环路径。
这个函数会找到两个节点之间的最短路径,或者返回false表示找不到路径(用php 5.6测试过):
function findpath(array $array, $start, $end, $steps = null)
$visited = []; // keep track of nodes already visited to avoid loops
$paths = [[$start]]; // array of paths to be checked
while ($path = array_pop($paths))
$node = end($path);
if ($node === $end)
return $path; // found path from start to end node
if ($steps !== null && count($path) > $steps)
continue; // path too long
$visited[$node] = true;
if (empty($array[$node]))
continue; // can't reach any other nodes from this path
foreach ($array[$node] as $next)
if (isset($visited[$next]))
continue; // already visited next node
// make new path by adding next node to current path
// then add new path to array of paths to be checked
$paths[] = array_merge($path, [$next]);
return false; // no paths left to check, cannot find path from start to end node
您可以选择为函数提供最大步数(例如路径 A -> B -> C -> D
为 3 步):
var_dump(findPath($array, 'A', 'D', 3));
// returns ['A', 'B', 'C', 'D']
var_dump(findPath($array, 'A', 'D', 2));
// returns false as path would be longer than 2 steps
var_dump(findPath($array, 'X1', 'X6'));
// returns ['X1', 'A', 'B', 'C', 'X6']
【讨论】:
以上是关于PHP在多维数组中查找路径的主要内容,如果未能解决你的问题,请参考以下文章
如何在 PHP 中展开多维数组(原始键访问路径存储为单个键)?