给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
始终以斜杠 '/' 开头。
两个目录名之间必须只有一个斜杠 '/' 。
最后一个目录名(如果存在)不能 以 '/' 结尾。
此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。
返回简化后得到的 规范路径 。
示例 1:
输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。
示例 2:
输入:path = "/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。
示例 3:
输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
示例 4:
输入:path = "/a/./b/../../c/"
输出:"/c"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/simplify-path
思路:创建一个栈,将除/之间的String进栈
- 每次进栈的时候看看栈顶,如果是..那么直接将..出栈
- 如果是 . 直接略过,因为./不会切换目录,仅仅是在本目录下
题目主要是判断的情况太多
public String simplifyPath(String path) {
LinkedList<String> stack = new LinkedList<>();
StringBuilder sb= new StringBuilder("");
char[] arr= path.toCharArray();
String t;
for(int i=arr.length-1;i>=0;i--)
{
//结尾可能没有/ 题目中没有说输入结尾一定是/
if(i==arr.length-1&&arr[i]=='/')
continue;
sb.delete(0, sb.length());
while (i>=1&&arr[i]!='/')
{
sb.insert(0, arr[i]);
i--;
if(i<=0)
break;
}
t=sb.toString();
if(t.equals(".")||t.equals(""))continue;
if(stack.isEmpty())
stack.push(t);
else
{
//看一下栈顶
if(stack.peek().equals("..")&&!t.equals(".."))
{
stack.pop();
continue;
}
stack.push(t);
}
}
StringBuilder res= new StringBuilder("");
res.append("/");//题目中明确说明开头为/
while (!stack.isEmpty())
{
if(stack.peek().equals("..")) {//这里为什么会加上..,是因为..只有碰到非 . 的时候才会出栈,如若非 . 的String不够那么..就会留在栈中。
stack.pop();
continue;
}
if(stack.isEmpty()) break;
res.append(stack.pop());
res.append("/");
}
if(res.length()>1) res.deleteCharAt(res.length()-1);//删除结尾的/
return res.toString();
}
方法二 Linux系统中处理路径的方法
public String simplifyPath(String path) {
LinkedList<String> queue= new LinkedList<>();
String[] arr=path.split("/");
for(String s:arr)
{
if(s.equals(".")||s.equals("")) continue;
if(s.equals(".."))
{
if(queue.isEmpty())continue;
queue.pollLast();
}else
{
queue.addLast(s);
}
}
return "/"+String.join("/",queue);
}