Given an absolute path for a file (Unix-style), simplify it. For example, path = "/home/", => "/home" path = "/a/./b/../../c/", => "/c"
先根据'/'的位置分割路径字符串,java可以直接用split函数,C++没有这个函数,需要遍历字符串判断当前字符是否为‘/’,并用substr提取两个‘/’之间的字符。分割子串后,考虑特殊情况:1.子串为“..”,意思为返回上级目录,这个操作让人很容易联想到栈,即把最近压入的目录“弹出”,栈顶就变成了上一级目录。2.子串为空或‘.’,意思是不变动目录,不作任何操作。综合考虑,我使用栈来当作存储路径的暂时容器,每读出一个不是特殊情况的字符串,就把它压入栈,每遇到".."就弹出一个栈顶元素,最后把栈中的元素重新拼接起来。
class Solution {
public:
string simplifyPath(string path) {
deque<string> st;
string tmp;
if(path.back()!='/') path.push_back('/');
int start=0;
for(int i=0; i<path.length(); i++) {
if(path[i]=='/') {
tmp=path.substr(start, i-start);
if(tmp=="..") {
if(!st.empty()) st.pop_back();
}
else if(tmp!="." && tmp!="") st.push_back(tmp);
start = i+1;
}
}
if(st.empty()) return "/";
string result = "";
while(!st.empty()) {
result = result+"/"+st.front();
st.pop_front();
}
return result;
}
};
代码实现中有几个细节,首先如果原路径不以‘/’结尾,则在末尾加上‘/’,这是因为循环中只有碰到‘/’才有机会把分割的子串压入栈中,如果最后不以‘/’结尾,就可能直接遍历完字符串而没有把最后一个分割子串压入栈。其次,实际的栈不是用stack,而是用deque实现,这是因为stack只能先入后出,在最后拼接路径时不能按正序输出子串。使用vector去实现栈也是可以的,但我测试了一下好像deque跑的速度快些。附:deque与vector的区别