给你一个字符串 path
,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/'
开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.
)表示当前目录本身;此外,两个点 (..
) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//'
)都被视为单个斜杠 '/'
。 对于此问题,任何其他格式的点(例如,'...'
)均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
- 始终以斜杠
'/'
开头。 - 两个目录名之间必须只有一个斜杠
'/'
。 - 最后一个目录名(如果存在)不能 以
'/'
结尾。 - 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含
'.'
或'..'
)。
返回简化后得到的 规范路径 。
示例 1:
输入:path = "/home/" 输出:"/home" 解释:注意,最后一个目录名后面没有斜杠。
示例 2:
输入:path = "/../" 输出:"/" 解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。
示例 3:
输入:path = "/home//foo/" 输出:"/home/foo" 解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
示例 4:
输入:path = "/a/./b/../../c/" 输出:"/c"
提示:
1 <= path.length <= 3000
path
由英文字母,数字,'.'
,'/'
或'_'
组成。path
是一个有效的 Unix 风格绝对路径。
class Solution {
public:
// 函数 simplifyPath 用于简化 Unix 风格的路径
string simplifyPath(string path) {
// 定义一个 lambda 函数 split,它接受一个字符串和一个分隔符,返回一个由分隔符分割的字符串向量
auto split = [](const string& s, char delim) -> vector<string> {
vector<string> ans; // 初始化一个空的字符串向量用于存放分割后的子字符串
string cur; // 当前子字符串
// 遍历输入字符串的每个字符
for (char ch : s) {
// 如果当前字符等于分隔符,则将当前子字符串添加到 ans 中,并清空当前子字符串
if (ch == delim) {
ans.push_back(move(cur));
cur.clear();
} else {
// 否则将当前字符添加到当前子字符串中
cur += ch;
}
}
// 将最后一个子字符串(如果存在)添加到 ans 中
ans.push_back(move(cur));
return ans; // 返回分割后的字符串向量
};
// 使用 split 函数按 '/' 分割路径字符串
vector<string> names = split(path, '/');
// 用一个 vector 作为栈来存储路径的每个部分
vector<string> stack;
// 遍历分割后的路径的每个部分
for(string& name:names){
// 如果部分是 "..",则从栈中弹出最后一个元素,模拟返回上级目录
if(name==".."){
if(!stack.empty())
stack.pop_back();
}
// 如果部分不是空字符串也不是 ".",则将其添加到栈中
else if(!name.empty()&&name!=".")
stack.push_back(name);
}
string ans; // 用于存放简化后的路径
// 如果栈为空,则返回根目录 "/"
if (stack.empty()) {
ans = "/";
} else {
// 否则,遍历栈中的每个元素,构造简化后的路径
for(string& name:stack){
ans+="/"+move(name);
}
}
return ans; // 返回简化后的路径
}
};
这段代码的思路如下:
-
首先定义了一个 lambda 函数 split,用于将字符串按照指定的分隔符分割成子字符串,并存放在一个字符串向量中。
-
使用 split 函数将输入的路径字符串按照 "/" 分割成多个子字符串,并存放在 names 向量中。
-
创建一个 stack 向量,用于模拟栈来存储路径的每个部分。
-
遍历分割后的路径的每个部分,在遍历过程中进行以下逻辑判断:
- 如果当前部分是 "..",则表示返回上级目录,从栈中弹出最后一个元素。
- 如果当前部分不是空字符串且不是 ".",则将其添加到栈中。
-
构造一个空的字符串 ans 用于存放简化后的路径。
-
如果栈为空,则表示路径是根目录,将根目录的符号 "/" 添加到 ans 中。
-
否则,遍历栈中的每个元素,将其添加到 ans 中,并在每个元素前面添加一个 "/"。
-
返回简化后的路径 ans。