标题文字
Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
click to show corner cases.
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风格的路径:
-
.
表示当前文件夹,即不进行任何操作 -
..
表示返回上层文件夹,如果已经至根目录,则不进行任何操作 -
/
表示路径的分割线,多个连续的/
等价于/
这里我们需要将复杂的unix路径,例如/a/./b/../../c/
简化成最简形式/c
思路和代码
从直观的角度思考,每当路径上我们遇到具有含义的操作符时,就对其当前的路径进行操作。我们可以首先将所有的内容从/
中分离出来,然后分别处理。这里我们需要用到堆栈的数据结构。堆栈有很多种实现方式,java中的Stack类LinkedList类都可以实现其功能。我们将读到的路径入栈,根据操作符出栈,最后将栈中剩余的元素组织成String路径返回即可。
代码如下:
public String simplifyPath(String path) {
Stack<String> s = new Stack<String>();
String[] pathDetail = path.split("/");
for(int i = 0 ; i < pathDetail.length ; i++){
//弹出上级目录,如果有上级目录
if(pathDetail[i].equals("..")){
if(s.isEmpty()){
continue;
}
s.pop();
//不进行任何操作
}else if(pathDetail[i].equals(".") || pathDetail[i].isEmpty()){
continue;
}else{
s.push(pathDetail[i]);
}
}
if(s.isEmpty()){
return "/";
}
StringBuilder result = new StringBuilder();
do{
result.insert(0, s.pop());
result.insert(0, "/");
}while(!s.isEmpty());
return result.toString();
}
也可以使用链表实现:
public String simplifyPath3(String path) {
Deque<String> stack = new LinkedList<>();
Set<String> skip = new HashSet<>(Arrays.asList("..",".",""));
for (String dir : path.split("/")) {
if (dir.equals("..") && !stack.isEmpty()) stack.pop();
else if (!skip.contains(dir)) stack.push(dir);
}
String res = "";
for (String dir : stack) res = "/" + dir + res;
return res.isEmpty() ? "/" : res;
}
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。