原题网址:https://leetcode.com/problems/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"
.
方法:通过栈来保存当前路径。
public class Solution {
/*
"./"
"/"
"/sa///./aa"
"/saaa"
"/."
"a/b/c/d///"
"/a/./b/../../c/"
"/home/../../.."
*/
public String simplifyPath(String path) {
char[] pa = path.toCharArray();
int pos = 0;
for(int i=0; i<pa.length; i++) {
if (pa[i] == '/') {
if (pos>0 && pa[pos-1] != '/') pa[pos++] = pa[i];
} else if (pa[i] == '.') {
if ((((pos==0) || (pos>0 && pa[pos-1] == '/')) && i+2<pa.length && pa[i+1]=='.' && pa[i+2]=='/')
|| (((pos==0) || (pos>0 && pa[pos-1] == '/')) && i+2==pa.length && pa[i+1]=='.')) {
//upper level
pos--;
while (pos>0 && pa[pos-1] != '/') pos --;
if (pos<0) pos = 0;
i ++;
} else if (((pos==0) || (pos>0 && pa[pos-1] == '/')) && (i+1==pa.length || (i+1<pa.length && pa[i+1] == '/'))) {
// same level
} else {
// normal dir
pa[pos++] = pa[i];
}
} else {
pa[pos++] = pa[i];
}
}
if (pos>0 && pa[pos-1] == '/') pos --;
char[] simplified = new char[pos+1];
simplified[0] = '/';
for(int i=0; i<pos; i++) simplified[i+1] = pa[i];
return new String(simplified);
}
}
词法和语法分开可以简化:
public class Solution {
public String simplifyPath(String path) {
String[] paths = path.split("/");
int len = 0;
for(int i=0; i<paths.length; i++) {
if ("..".equals(paths[i])) {
len = Math.max(--len, 0);
} else if (!"".equals(paths[i]) && !".".equals(paths[i])) {
paths[len++] = paths[i];
}
}
StringBuilder sb = new StringBuilder("/");
for(int i=0; i<len; i++) {
sb.append(paths[i]);
if (i<len-1) sb.append("/");
}
return sb.toString();
}
}