Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/"
, => "/home"
path = "/a/./b/../../c/"
, => "/c"
- 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"
.
Code:
/**
*
*/
package From61;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.Stack;
/**
* @author MohnSnow
* @time 2015年7月1日 上午10:58:22
* @translate 給定一個Unix風格的路徑,簡化之。使其不改變路徑的結果,但是去掉中間無用的字符。
* 因爲系統執行的時候也是逐段查看的,因此最直觀的做法就是使用棧來簡化,
* 當是/..時,出棧;
* 當是/.時,忽視;
* 當是//a時進棧/a;
* 當是其他時才進棧。
*/
public class LeetCode71 {
/**
* @param argsmengdx
* -fnst
*/
public static String simplifyPath1(String path) {
Set<String> isSkip = new HashSet<>(Arrays.asList("", ".", ".."));
Deque<String> stack = new ArrayDeque<>();
System.out.println(Arrays.toString(path.split("/")));
for (String token : path.split("/")) {
if (token.equals("..") && !stack.isEmpty())
stack.pop();
if (isSkip.contains(token))
continue;
stack.push(token);
}
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()) {
sb.append("/" + stack.pollLast());
}
return sb.length() == 0 ? "/" : sb.toString();
}
//348msAC----path.split("/")的應用是經典
public static String simplifyPath2(String path) {
Deque<String> stack = new ArrayDeque<String>();
for (String token : path.split("/")) {
if (token.equals("..") && !stack.isEmpty())
stack.pop();
if (token.equals(".") || token.equals("") || token.equals(".."))
continue;
stack.push(token);
}
System.out.println(stack.toString());
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()) {
sb.append("/" + stack.pollLast());
}
return sb.length() == 0 ? "/" : sb.toString();
}
//https://leetcode.com/discuss/22592/java-10-lines-solution-with-stack
public static 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;
}
public static String simplifyPath(String path) {
StringBuffer result = new StringBuffer();
int last = 0;
while (last < path.length()) {
if (last == (path.length() - 1) && path.charAt(last) == '/') {// 最後一個是/
break;
}
result.append('/');
while (last + 1 < path.length() && '/' == path.charAt(last + 1)) {// //--->/
last++;
}
if (last + 1 < path.length() && '.' == path.charAt(last + 1) && '.' == path.charAt(last)) {// /..----out
last++;
last++;
result.deleteCharAt(result.length() - 1);
while (result.charAt(result.length() - 1) != '/') {
result.deleteCharAt(result.length() - 1);
}
result.deleteCharAt(result.length() - 1);
continue;
}
if (last + 1 < path.length() && '.' == path.charAt(last + 1)) {// /.--->忽略此次情況
last++;
result.deleteCharAt(result.length() - 1);
continue;
}
while (last < path.length() && '/' != path.charAt(last)) {// /home--->加入
result.append(path.charAt(last));
last++;
}
}
return result.toString();
}
public static void main(String[] args) {
String path = "/home/a/..//a/..";
System.out.println("path: " + path);
//System.out.println("simplifyPath: " + simplifyPath(path));
System.out.println("simplifyPath1: " + simplifyPath1(path));
System.out.println("simplifyPath2: " + simplifyPath2(path));
System.out.println("simplifyPath3: " + simplifyPath2(path));
}
}