Given an absolute path for a file (Unix-style), simplify it.
For example,
path = “/home/”, => “/home”
path = “/a/./b/../../c/”, => “/c”
Corner Cases:
Did you consider the case where path = “/../”?
-In this case, you should return “/”.Another corner case is the path might contain multiple slashes ‘/’
together, such as “/home//foo/”.
-In this case, you should ignore redundant slashes and return “/home/foo”.
s思路:
1. 看了半天,没看懂如何理解’.’和’..’的作用。参考了大神http://www.cnblogs.com/grandyang/p/4347125.html 遇到’.’就直接ignore,遇到’..’则返回母目录,而不是子目录。所以:
path = "/a/./b/../c/", => "/a/c"
path = "/a/./b/c/", => "/a/b/c"
2. 对这种需要穿梭在不同层的数据的应用,当之无愧应该是用stack来做了。这里用vector来代替stack,提高速度!
//方法1:代码不够利索,又臭又长!
class Solution {
public:
string simplifyPath(string path) {
//
string res="";
vector<string> ss;
for(int i=0;i<path.size();i++){
string cur="";
if(path.substr(i,2)=="/."&&i+2==path.size()||path.substr(i,3)=="/./"){i++;continue;}
if((path.substr(i,3)=="/.."&&i+3==path.size()||path.substr(i,4)=="/../")){
i+=2;
if(!ss.empty())
ss.pop_back();
}else if(path[i]!='/'){
int j=i;
while(j<path.size()&&path[j]!='/'){//bug:加保护!
j++;
}
ss.push_back(path.substr(i,j-i));
i=j-1;
}
}
if(ss.empty()) return "/";
for(auto s:ss){
res+='/';
res+=s;
}
return res;
}
};
**//方法2**:参考了http://www.cnblogs.com/grandyang/p/4347125.html
//**简洁太多了。代码简洁==思路清晰**。这里就是用两个参数start,len去表示/之间的字符串,并根据这两个参数取出这个substring和".."以及"."比较。不断的取,不断的比,决定是从stack push 还是pop。
class Solution {
public:
string simplifyPath(string path) {
//
string res="";
vector<string> ss;
int i=0;
while(i<path.size()){
while(i<path.size()&&path[i]=='/') i++;
if(i==path.size()) break;
int start=i;
while(i<path.size()&&path[i]!='/') i++;
string cur=path.substr(start,i-start);
if(cur==".."){
if(!ss.empty()) ss.pop_back();
}else if(cur!="."){
ss.push_back(cur);
}
}
for(auto s:ss){
res+='/'+s;
}
return res.empty()?"/":res;
}
};