Given an absolute path for a file (Unix-style), simplify it.
For example,
path = “/home/”, => “/home”
path = “/a/./b/../../c/”, => “/c”
这道题让简化给定的路径,光根据题目中给的那一个例子还真不太好总结出规律,应该再加上两个例子 path = “/a/./b/../c/”, => “/a/c”和path = “/a/./b/c/”, => “/a/b/c”, 这样我们就可以知道中间是”.”的情况直接去掉,是”..”时删掉它上面挨着的一个路径,而下面的边界条件给的一些情况中可以得知,如果是空的话返回”/”,如果有多个”/”只保留一个。那么我们可以把路径看做是由一个或多个”/”分割开的众多子字符串,把它们分别提取出来一一处理即可,代码如下:
class Solution {
public:
string simplifyPath(string path) {
vector<string> v;
int i = 0;
while(i < path.size()) {
while(path[i] == '/' && i < path.size())
++i;
if(i == path.size())
break;
int start = i;
while(path[i] != '/' && i < path.size())
++i;
int end = i - 1;
string s = path.substr(start, end - start + 1);
if(s == "..") { //字符用单引号,字符串用双引号!
if(!v.empty())
v.pop_back();
}
else if(s != ".") {
v.push_back(s);
}
}
if(v.empty())
return "/";
string res;
for(int i = 0; i < v.size(); ++i) {
res += '/' + v[i];
}
return res;
}
};
C++中也有专门处理字符串的机制,我们可以使用stringstream来分隔字符串,然后对每一段分别处理,思路和上面的方法相似,参见代码如下:
class Solution {
public:
string simplifyPath(string path) {
string res, t;
stringstream ss(path);
vector<string> v;
while (getline(ss, t, '/')) {
if (t == "" || t == ".") continue;
if (t == ".." && !v.empty()) v.pop_back();
else if (t != "..") v.push_back(t);
}
for (string s : v) res += "/" + s;
return res.empty() ? "/" : res;
}
};
笔记:分情况讨论,现将字符串存入vector,出现../就pop_back()最后的地址字符串,最后逐个取出,存成正确的地址格式即可。