以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。更多信息请参阅:Linux / Unix中的绝对路径 vs 相对路径
请注意,返回的规范路径必须始终以斜杠 / 开头,并且两个目录名之间必须只有一个斜杠 /。最后一个目录名(如果存在)不能以 / 结尾。此外,规范路径必须是表示绝对路径的最短字符串。
输入:"/a//bc/d//././/.." 输出:"/a/b/c"
题解:
我想到的办法真的很愚蠢,就是每次push当前位置,同时判断与后面位置的关系,如果是"..",就删除前一个;这样就需要考虑多种情况;比如"...aa"等
class Solution {
public:
string simplifyPath(string path) {
int size = path.size();
list<char> clearPath;
clearPath.push_back(path[0]);
for(int i = 1;i < size;i++)
{
if(path[i]=='.')
{
if(i+1<size && isalpha(path[i+1])){
clearPath.push_back(path[i]);
continue;
}
//处理 .. 情况
if(i+1<size && path[i+1]=='.'){
if(i+2<size && path[i+2]!='/'){
clearPath.push_back('.');
clearPath.push_back('.');
while(i+2<size && path[i+2]!='/'){
clearPath.push_back(path[i+2]);
i++;
}
i++;
continue;
}
//if(i+2<size && isalpha(path[i+2])){
// clearPath.push_back(path[i]);
// continue;
//}
if(clearPath.size()>1){
//cout<<"pop '/': "<<clearPath.top()<<endl;
clearPath.pop_back();
while(clearPath.back()!='/')
{
//cout<<"pop alpha: "<<clearPath.top()<<endl;
clearPath.pop_back();
}
i++;
}
}
}
else if(isalpha(path[i])) //是字母的情况
{
clearPath.push_back(path[i]);
//cout<<"push alpha: "<<clearPath.top()<<endl;
}
else{ //是’/‘的情况
if(clearPath.back()!='/')
{
clearPath.push_back(path[i]);
//cout<<"push '/': "<<clearPath.top()<<endl;
}
}
}
while(clearPath.back()=='/'&&clearPath.size()>1){
clearPath.pop_back();
}
string res;
size = clearPath.size();
while(!clearPath.empty()){
res+=clearPath.front();
clearPath.pop_front();
}
return res;
}
};
正确题解:
其实直接可以用'/'分割字符串;只会得到四种情况:""、"."、".."、路径;用栈来压入,只要判断当前是否是".."&&前一个是否为空即可。
class Solution {
public:
string simplifyPath(string path) {
stringstream is(path);
vector<string> strs;
string res = "", tmp = "";
while(getline(is, tmp, '/')) {
if(tmp == "" || tmp == ".")
continue;
else if(tmp == ".." && !strs.empty())
strs.pop_back();
else if(tmp != "..")
strs.push_back(tmp);
}
for(string str:strs)
res += "/" + str;
if(res.empty())
return "/";
return res;
}
};