给你一个字符串 path
,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/'
开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.
)表示当前目录本身;此外,两个点 (..
) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//'
)都被视为单个斜杠 '/'
。 对于此问题,任何其他格式的点(例如,'...'
)均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
- 始终以斜杠
'/'
开头。 - 两个目录名之间必须只有一个斜杠
'/'
。 - 最后一个目录名(如果存在)不能 以
'/'
结尾。 - 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含
'.'
或'..'
)。
返回简化后得到的 规范路径 。
下面解释算法流程:
- 将输入的路径字符串path按照"/"分割成一个字符串数组parts。
- 创建一个栈stack,用于存储路径中的目录名。
- 遍历parts数组中的每个目录名str:
- 如果str等于".."(表示返回上级目录):
- 如果栈不为空:
- 弹出栈顶的目录名,相当于返回上级目录。
- 如果栈不为空:
- 如果str不等于"."且不为空(即不是当前目录和空字符串):
- 将str压入栈中,相当于进入该目录。
- 如果str等于".."(表示返回上级目录):
- 创建一个StringBuilder sb,用于拼接简化后的路径。
- 如果原始路径path以"/"开头,在sb中添加一个"/"。
- 从栈底开始,依次将栈中的目录名弹出并添加到sb中,中间用"/"分隔。
- 将sb转换为字符串re。
- 如果re的长度大于1且以"/"结尾(但不包括只有一个"/"的情况),去掉最后一个"/"。
- 返回简化后的路径re。
import java.util.Stack;
public class no_71 {
public static void main(String[] args) {
String path = "/home/";
System.out.println(simplifyPath(path));
}
public static String simplifyPath(String path) {
String[] parts = path.split("/");
Stack<String> stack = new Stack<>();
for (String str : parts) {
if (str.equals("..")) {
if (!stack.isEmpty())
stack.pop();
} else if (!str.equals(".") && !str.isEmpty()) {
stack.push(str);
}
}
StringBuilder sb = new StringBuilder();
if (path.startsWith("/")) sb.append("/");
while (!stack.isEmpty()) {
sb.insert(0, stack.pop());
if (!stack.isEmpty()) {
sb.insert(0, "/");
}
}
String re = sb.toString();
if (!re.startsWith("/")) re = "/" + re;
return re.length() > 1 && re.endsWith("/") ? re.substring(0, re.length() - 1) : re;
}
}