以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (…) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。更多信息请参阅:Linux / Unix中的绝对路径 vs 相对路径
请注意,返回的规范路径必须始终以斜杠 / 开头,并且两个目录名之间必须只有一个斜杠 /。最后一个目录名(如果存在)不能以 / 结尾。此外,规范路径必须是表示绝对路径的最短字符串。
示例 1:
输入:"/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。
示例 2:
输入:"/…/"
输出:"/"
解释:从根目录向上一级是不可行的,因为根是你可以到达的最高级。
示例 3:
输入:"/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
示例 4:
输入:"/a/./b/…/…/c/"
输出:"/c"
示例 5:
输入:"/a/…/…/b/…/c//.//"
输出:"/c"
示例 6:
输入:"/a//bc/d//././/…"
输出:"/a/b/c"
来源:力扣(LeetCode)
敲到最后发现有几个特别的过不去,如果只是为了A,那特判即可。
说一下思路,就是以‘/’为边界分割字符串,如果是“。。”那么出栈;如果是“。”,不管即可;如果是其他目录,入栈即可
所以就是如何分割字符串了。C语言可以用 stroke,c++可以用stringstream和getline,java 可以用split即可
/*c++版,模拟分割*/
class Solution {
public:
string simplifyPath(string path) {
path+='/';
stack<string>st;//当时用的char,没想到啊
string tep;
for(auto am : path){
if(am=='/'){
if(tep==".."){
if(!st.empty())st.pop();
}else if(tep=="."){
}else if(!tep.empty()){
st.push(tep);
}
tep.clear();
}
else tep+=am;
}
string ans;
int size=st.size();
for(int i=0;i<size;i++){
//后面有翻转,这里先翻转。负负得正
ans+=string(st.top().rbegin(),st.top().rend())+'/';
st.pop();
}
reverse(ans.begin(),ans.end());
return ans.empty()?"/":ans;
}
};
/* c++ stringstream 与getline ,这里为了简便用vector模拟栈,更加节约时间
*/
string simplifyPath(string path) {
vector<string>st;
stringstream str;
str.str(path);
string tep="";
while(getline(str,tep,'/')){
if(tep==".."){
if(!st.empty()) st.pop_back();
}
else if(tep==".");
else if(!tep.empty()) st.push_back('/'+tep);
}
string ans;
for(auto a:st) ans+=a;
return ans.empty()?"/":ans;
}
istream& getline (istream& is, string& str, char delim);
is :表示一个输入流,例如 cin。所以我们要把string 转为流
str :string类型的引用,用来存储输入流中的流信息。
delim :char类型的变量,所设置的截断字符;在不自定义设置的情况下,遇到’\n’,则终止输入。