71. Simplify Path
Medium
4081140FavoriteShare
Given an absolute path for a file (Unix-style), simplify it. Or in other words, convert it to the canonical path.
In a UNIX-style file system, a period .
refers to the current directory. Furthermore, a double period ..
moves the directory up a level. For more information, see: Absolute path vs relative path in Linux/Unix
Note that the returned canonical path must always begin with a slash /
, and there must be only a single slash /
between two directory names. The last directory name (if it exists) must not end with a trailing /
. Also, the canonical path must be the shortest string representing the absolute path.
Example 1:
Input: "/home/"
Output: "/home"
Explanation: Note that there is no trailing slash after the last directory name.
Example 2:
Input: "/../"
Output: "/"
Explanation: Going one level up from the root directory is a no-op, as the root level is the highest level you can go.
Example 3:
Input: "/home//foo/"
Output: "/home/foo"
Explanation: In the canonical path, multiple consecutive slashes are replaced by a single one.
Example 4:
Input: "/a/./b/../../c/"
Output: "/c"
Example 5:
Input: "/a/../../b/../c//.//"
Output: "/c"
Example 6:
Input: "/a//bc/d//././/.."
Output: "/a/b/c"
这道题我放到VS里调了多次才一步一步最终接近答案,test case太多太恶心。
比如这样的testcase:
真的是试了很多遍才试出来,不怕麻烦的可以自己尝试着做做。
下面说一下整理路径的策略(这个题目里写的不够清楚,直接导致了这么多次提交错误):
1.首先需要搜集路径,从左到右搜集,放到一个数组中ans
2.在搜集路径过程中,如果遇到/../或者/..(结束),需要从数组ans中弹出一个路径(pop_back)
3.在搜集路径过程中,如果遇到/.../或者/...(结束),需要把...加入到ans中(这一点很难想到,要出错了才知道)
4.除了路径以外的内容统统先扔掉
5.得到路径数组以后,把/加上去,拼出答案k
下面是AC的答案,判断条件中的边界需要特别注意,很容易出错,还有a溢出的问题,有个地方是需要a--还原的:
class Solution {
public:
string simplifyPath(string path) {
int a = 0;
//int b=0;
vector<string> ans;
ans.clear();
//下面开始记录路径数组
for (; a < path.length(); a++)//从第一个字母开始,从左到右挨个过滤
{
if (path[a] != '/'&&path[a] != '.')//第一种情况:如果是字母
{
string tempStr = "";
while (a < path.length() && path[a] != '/'&&path[a] != '.')//从第一个字母开始把一串没被/分开的字符串记录下来,直到下一个/或者.
{
tempStr += path[a];
a++;
}
a--;//此时a已经指向/,需要倒回去一位
ans.push_back(tempStr);//将这个字符串压入数组
}
else if (path[a] == '/')//第二种情况:如果是/
{
//去掉的第一种情况是/./或者/.(结束)
if ((a + 2 < path.length() && path[a + 1] == '.'&&path[a + 2] == '/') || (a + 2 == path.length() && path[a + 1] == '.'))a++;
//去掉的第二种情况是/../或者/..(结束)
else if ((a + 3 < path.length() && path[a + 1] == '.'&&path[a + 2] == '.'&&path[a + 3] == '/') || (a + 3 == path.length() && path[a + 1] == '.'&&path[a + 2] == '.'))
{
a = a + 2;
if (ans.size() >= 1)ans.pop_back();
}
//保留...
else if(a + 1 < path.length() && path[a + 1] == '.')
{
string tempStr = "";
a++;
while (a < path.length() && path[a] != '/')
{
tempStr += path[a];
a++;
}
a--;
ans.push_back(tempStr);
}
}
}
string k = "/";
if (ans.size() == 0)return "/";
for (int p = 0; p < ans.size() - 1; p++)
{
k += ans[p];
k += "/";
}
k += ans[ans.size() - 1];
//if (k.length() == 0)k = "/";
return k;
}
};