Simplify Path
Posted ncznx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Simplify Path相关的知识,希望对你有一定的参考价值。
描述
Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
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".
分析
这是一道简化路径的题,路径简化的依据是:
当遇到“/../"则需要返回上级目录,需检查上级目录是否为空。
当遇到"/./"则表示是本级目录,无需做任何特殊操作。
当遇到"//"则表示是本级目录,无需做任何操作。
当遇到其他字符则表示是文件夹名,无需简化。
当字符串是空或者遇到”/../”,则需要返回一个"/"。
当遇见"/a//b",则需要简化为"/a/b"。
根据这些要求,我需要两个栈来解决问题。
先将字符串依"/"分割出来,然后检查每个分割出来的字符串。
当字符串为空或者为".",不做任何操作。
当字符串不为"..",则将字符串入栈。
当字符串为"..", 则弹栈(返回上级目录)。
代码
1 import java.util.ArrayList; 2 3 public class SimplifyPath { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 String path = "/a/./b/../../c/"; 8 // String path = "/home/"; 9 // String[] strs = path.split("/"); 10 // if(strs[4]=="..") 11 // if(strs[4].equals("..")) 12 // System.out.println(true); ==比较的是2个对象的地址,而equals比较的是2个对象的内容。 13 System.out.println(simplifyPath(path)); 14 } 15 16 public static String simplifyPath(String path) { 17 ArrayList<String> dirs = new ArrayList<String>(); // 当做栈 18 String[] strs = path.split("/"); 19 for (int i = 0; i < strs.length; i++) { 20 // dirs.add(strs[i]); 21 if (!strs[i].equals("") && !strs[i].equals(".")) {// 当有连续 ‘///‘ 时,dir 为空 22 if (strs[i] .equals("..")) { 23 if (dirs.size()!=0) 24 dirs.remove(dirs.size() - 1); 25 } else { 26 dirs.add(strs[i]); 27 } 28 } 29 30 } 31 StringBuffer out = new StringBuffer(); 32 if (dirs.size()==0) { 33 out.append("/"); 34 35 } else { 36 for (String dir : dirs) 37 out.append("/").append(dir); 38 } 39 return out.toString(); 40 } 41 42 }
栈操作方法(转):
1 public String simplifyPath(String path) { 2 if(path == null||path.length()==0) 3 return path; 4 5 Stack<String> stack = new Stack<String>(); 6 String[] list = path.split("/"); 7 8 for(int i=0; i<list.length; i++){ 9 if(list[i].equals(".")||list[i].length()==0) 10 continue; 11 else if(!list[i].equals("..")) 12 stack.push(list[i]); 13 else{ 14 if(!stack.isEmpty()) 15 stack.pop(); 16 } 17 } 18 19 StringBuilder res = new StringBuilder(); 20 21 Stack<String> temp = new Stack<String>(); 22 while(!stack.isEmpty()) 23 temp.push(stack.pop()); 24 25 while(!temp.isEmpty()) 26 res.append("/"+temp.pop()); 27 28 if(res.length()==0) 29 res.append("/"); 30 31 return res.toString(); 32 }
注意:
判断字符串相等与否要用.equals(),因为是引用类型。
要注意split函数是可以split出空字符的,例如://b/ 会被split结果为["","b"]。
最后使用StringBuilder进行拼接,由于String在每次对字符串修改时候均会生成一个新的String,效率较低,一般会采用StringBuilder或者StringBuffer来进行字符串修改的操作,StringBuilder是StringBuffer的简易替换,是非线程安全的,而StringBuffer是线程安全的。
在网上还看到有人写的最后还原path没用到第二个栈,是因为可以利用Java中LinkedList 数据类型来表示第一个栈。LinkedList数据类型很强大,包含了栈和队列的实现。所以最后还原时调用removeLast()函数就可以解决顺序问题。
以上是关于Simplify Path的主要内容,如果未能解决你的问题,请参考以下文章