一道PHP面试题,求两个文件的相对路径

首先原题是这样子的:
php

写一个函数,计算出两个文件的相对路径,如 $a = '/a/b/c/d/d.php',$b = '/a/b/1/2/c.php'函数

计算出的$b相对于$a的相对路径应该是:../../c/d测试

那么对于网上给出的答案,看了看貌似只能针对题目中给出的那个路径来计算,若是路径一变化,相似下面这样,那么那些程序好像没用了,固然有些是有用,可是仍是报一些警告出来。。。。。spa

例如:code

$a = '/a/b/c/d/e/f/g/h/e.php'get

$b = '/a/b/1/2/c.php'string

再例如:io

$a = '/a/e.php'function

$b = '/a/b/c/d/1/2/c.php'class

再例如:

$a = '/a/b/c/d/d.php'

$b = '/a/b/c/d/c.php'

因此这个状况挺多的,不能仅仅看当下的需求!

首先仍是说下这个题目的意图吧,它的要求是求$b相对于$a的一个相对路径,也就是说是个什么意思呢。

就是从$b所给定的那个文件经过相对路径的方式表示怎么样能够找到$a所对应的那个文件。就那题目给出的那个路径来解释,就是咱们怎么$b到达$a呢,那首先从$b出发须要“../”上一级目录而后再“../”上一级目录来到了“/a/b”这个目录下,而后接着再从这个目录下出发,链接上“/c/d”而后就来到了$a所对应的目录。

也就是说,这个题目的主要任务是找到从$b到$a须要“上几级”才能到达和$a具备相同目录的地方,而后接着链接上$a接下来的那部分,那么咱们就获得了答案,因此题目的关键是找到底须要“上几级”!

废话很少说,直接看代码:

/**
 * 计算$b相对于$a的相对路径
 * @param string $a
 * @param string $b
 * @return string
 */
function getRelativePath($a, $b) {
	$relativePath = "";
	$pathA = explode('/', dirname($a));
	$pathB = explode('/', dirname($b));
	$n = 0;
	$len = count($pathB) > count($pathA) ? count($pathA) : count($pathB);
	do {
		if ( $n >= $len || $pathA[$n] != $pathB[$n] ) {
			break;
		}
	} while (++$n);
	$relativePath .= str_repeat('../', count($pathB) - $n);
	$relativePath .= implode('/', array_splice($pathA, $n));
	return $relativePath;
}
$res = getRelativePath($a, $b);
var_dump($res);

通过测试呢,上面列举的状况都知足。

那这段程序须要解释的就是:

$len为何须要求出$a和$b中路径最少的一个?

那是由于下面咱们经过do{}while();循环来从0即起始路径开始向下一直对比$a和$b的路径,但愿找到是从哪一个路径开始致使$a和$b不同了,也就是从找到了$a和$b路径总共相同的路径数是几个了。那在寻找的过程当中,若是出现$a和$b的路径一直不相等那么$n会一直增长致使陷入死循环,因此还须要另一个条件,就是咱们须要让$n的最大值不能超过$a和$b中路径最短的一个,为何呢?由于$n一旦大于了$len那说明有一个路径已经结束了,那直到结束也没有找到$a和$b不同的那个部分,那说明其中最短路径的长度正好是他们路径相同的数目。(多数其它程序就范了这个错误),也就不须要继续找了,由于咱们已经找到了。

找到了相同路径的个数以后,首先须要计算的是:从$b到$a到底须要几个“../”,那么计算方法就是用“count($pathB) - $n”,为何呢?由于$n表示路径相同的数目,而“ count($pathB)”表示$b的路径数,那么相互一减就获得了不一样的路径数目也就是须要的几个“../”,那么减完以后的结果必定是大于等0的值,因此没问题!

找到了从$b到$a须要几个“../”以后的任务就是将这几个“../”和$a中不一样的路径部分拼接一下就能够了,也就是代码:$relativePath .= implode('/', array_splice($pathA, $n));

到此,结束!

相关文章
相关标签/搜索