需求:给定绝对路径A和绝对路径B,计算B相对于A的路径,例如A=/srv/test/ , B=/srv/foo/bar ,则结果为 ../foo/bar 。
思路:把A和B中具有相同的前面部分全部去掉,A中剩下的部分,有几个目录就替换为几个 ../ ,再把结果拼上 B的剩余部分就是结果。
从PHP手册看到有人写的一个函数:
<?php
function relativePath($from, $to, $ps = DIRECTORY_SEPARATOR)
{
$arFrom = explode($ps, rtrim($from, $ps));
$arTo = explode($ps, rtrim($to, $ps));
while(count($arFrom) && count($arTo) && ($arFrom[0] == $arTo[0]))
{
array_shift($arFrom);
array_shift($arTo);
}
return str_pad("", count($arFrom) * 3, '..'.$ps).implode($ps, $arTo);
}
?>
假定参数分别为 from=/srv/test/ , to=/srv/foo/bar,上面的函数运行
10000次时间约为
0.1s 。
自己写个C版本的函数呢?看看效率如何?
#include <stdio.h>
#include <stdlib.h>
#define RESULT_LENGTH 100;
void relative_path(char *from,char *to, char *result){
int i,j,k;
i = j = 0;
while(from[i] != '\0' && to[i] != '\0' && from[i] == to[i]){
i++;
}
k = i;
while(from[k] != '\0'){
if(from[k++] == '/'){
result[j++]='.';
result[j++]='.';
result[j++]='/';
}else{
continue;
}
}
while(to[i] != '\0'){
result[j++] = to[i++];
}
result[j] = '\0';
}
int main(int argc, char *argv[]){
char *from = argv[1];
char *to = argv[2];
char *result;
result = (char *)malloc(sizeof(char)*RESULT_LENGTH);
int i;
for(i=0;i<10000000;i++){
relative_path(from,to,result);
}
printf("%s\n",result);
free(result);
result = NULL;
return 0;
}
假定参数分别为 from=/srv/test/ , to=/srv/foo/bar,上面的函数运行
1000万次时间约为
0.4s 。
好吧,对比一下,差距接近250倍。