Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/"
, => "/home"
path = "/a/./b/../../c/"
, => "/c"
Corner Cases:
» Solve this problem
- 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"
.
又是一个字符串处理题。
面对这种题目一定要保持清醒,先分析好题目之后再开始码代码。
题目的要求是输出Unix下的最简路径,Unix文件的根目录为"/","."表示当前目录,".."表示上级目录。
例如:
输入1:
/../a/b/c/./..
输出1:
/a/b
模拟整个过程:
1. "/" 根目录
2. ".." 跳转上级目录,上级目录为空,所以依旧处于 "/"
3. "a" 进入子目录a,目前处于 "/a"
4. "b" 进入子目录b,目前处于 "/a/b"
5. "c" 进入子目录c,目前处于 "/a/b/c"
6. "." 当前目录,不操作,仍处于 "/a/b/c"
7. ".." 返回上级目录,最终为 "/a/b"
我用一个堆栈来模拟路径的行为,遇到"."不操作,遇到".."退栈,其他情况都压入堆栈。
P.S.
有以"."开头的路径,例如:"/.fdfd"。
class Solution {
private:
void pathToDirectories(stack<string> &directories, string &path) {
string name;
name.clear();
path += '/';
for (int i = 0; i < path.size(); i++) {
if (path[i] == '/') {
if (!name.empty()) {
if (name[0] == '.' && name.size() == 2 && name[1] == '.') {
if (!directories.empty()) {
directories.pop();
}
}
else if (!(name[0] == '.' && name.size() == 1)) {
directories.push(name);
}
}
name.clear();
}
else {
name += path[i];
}
}
}
void directoriesToPath(string &answer, stack<string> &directories) {
answer.clear();
while (!directories.empty()) {
answer = directories.top() + '/' + answer;
directories.pop();
}
if (!answer.empty()) {
answer = answer.substr(0, answer.size() - 1);
}
answer = '/' + answer;
}
public:
string simplifyPath(string path) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
stack<string> directories;
pathToDirectories(directories, path);
string answer;
directoriesToPath(answer, directories);
return answer;
}
};