地址:https://leetcode.com/problems/simplify-path/
题目:
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//.//"
, => "/c"
path = "/a//bc/d//././/.."
, => "/a/b/c"
In a UNIX-style file system, a period (’.’) refers to the current directory, so it can be ignored in a simplified path. Additionally, a double period ("…") moves up a directory, so it cancels out whatever the last directory was. For more information, look here: https://en.wikipedia.org/wiki/Path_(computing)#Unix_style
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"
.
理解:
按规则往下读就可以了。可以把每次读出来的文件夹记录下来,如果有..
且记录不为空,则把最后的弹出来即可。
实现1:
下面是我最开始的实现,这种实现在遇到"/..."
这种输入的时候有问题,我的写法读了两个…并忽略了下一个,并没有想到会有这种输入。。
class Solution {
public:
string simplifyPath(string path) {
vector<string> paths;
size_t len = path.length();
size_t curr = 0;
while (curr < len) {
if (path[curr] == '/') {
++curr;
continue;
}
else if (path[curr] == '.') {
++curr;
if (curr< len&&path[curr] == '.') {
++curr;
if (paths.empty())
continue;
paths.pop_back();
}
}
else {
string tmp;
while (curr < len&&path[curr] != '/'&&path[curr] != '.') {
tmp += path[curr];
++curr;
}
paths.push_back(tmp);
}
}
string res;
if(paths.empty())
res="/";
else {
for (auto s : paths)
res = res + "/" + s;
}
return res;
}
};
优化一下
class Solution {
public:
string simplifyPath(string path) {
vector<string> paths;
size_t len = path.length();
size_t curr = 0;
while (curr < len) {
while (curr < len&&path[curr] == '/')
++curr;
if (curr == len) break;
int j = curr;
while (j < len&&path[j] != '/')
++j;
string tmp = path.substr(curr, j - curr);
curr = j;
if (tmp == "..") {
if (!paths.empty())
paths.pop_back();
}
else if(tmp!=".")
paths.push_back(tmp);
}
string res;
if (paths.empty())
res = "/";
else {
for (auto s : paths)
res = res + "/" + s;
}
return res;
}
};
实现2:
这种实现利用了getline,涨姿势了,原来还能这么用。不过好慢啊。
class Solution {
public:
string simplifyPath(string path) {
vector<string> paths;
string tmp;
istringstream in(path);
while (getline(in, tmp, '/')) {
if (tmp == "" || tmp == ".") continue;
if (tmp == "..") {
if (!paths.empty()) paths.pop_back();
}
else
paths.push_back(tmp);
}
string res;
if(paths.empty())
res="/";
else {
for (auto s : paths)
res = res + "/" + s;
}
return res;
}
};