71 简化路径
给你一个字符串 path
,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/'
开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.
)表示当前目录本身;此外,两个点 (..
) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//'
)都被视为单个斜杠 '/'
。 对于此问题,任何其他格式的点(例如,'...'
)均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
- 始终以斜杠
'/'
开头。 - 两个目录名之间必须只有一个斜杠
'/'
。 - 最后一个目录名(如果存在)不能 以
'/'
结尾。 - 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含
'.'
或'..'
)。
返回简化后得到的 规范路径 。
示例 1:
输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。
示例 2:
输入:path = "/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。
示例 3:
输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
示例 4:
输入:path = "/a/./b/../../c/"
输出:"/c"
理解题意:给定一个路径path,进行简化,分为如下几种情况:
- 多个连续斜杠’///'简化为一个 ‘/’
- 一个点’.'表示当前目录,直接去除即可
- 两个点’…'表示上级目录,需返回到上一级
解题思路:
-
当遇到两个点时,需返回上级目录,类似于栈弹出栈顶元素的操作,因此想到使用栈!
-
为什么栈只存储文件名,不存储’/'?存在多个连续斜杠的情况需要去除,且不便于返回上级目录(弹出栈顶元素),故不存储!
实际操作: 用一个栈维护路径中的 文件/目录名
- 用
vector
模拟stack
,最后便于返回目录
遍历路径path
,分为两种情况:
-
遇到
'/'
,直接跳过,不做操作 -
遇到非斜杠,统计两斜杠间的字符串,再进行判断!
- 当为一个点’.'时,表示同级目录,不进行操作 跳过
- 当为两个点’…'表示上级目录,弹出栈顶元素,即返回上级目录,注意:可能当前在根目录(栈为空),根目录没有上一级,则直接跳过即可
- 当为其余字符即文件名时,直接入栈
代码如下:
string simplifyPath(string path) {
vector<string> stk; //vector模拟栈
int n = path.size(), i = 0;
string str = "";
while (i < n) {
//遇到 / 一直往后,直到非斜杠
if (path[i] == '/')
++i;
else {
//将两斜杠间的字符组成串,再进行判断
for (; i < n && path[i] != '/'; ++i)
str += path[i];
if (str == ".") ; //当前目录,什么都不做
else if (str == "..") {
//返回上级目录(弹出栈顶元素)
if (!stk.empty())
stk.pop_back();
}
//其余情况都认为是文件或目录名
else
stk.push_back(str);
//str置空,用于存储下一个文件名
str = "";
}
}
if (stk.empty()) //栈为空表示仍在根目录
return "/";
string ans = "";
for (auto& s : stk)
//注意补'/'
ans += ('/' + s);
return ans;
}