需求:给定绝对路径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倍。