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.

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".
这道题就是化简地址,有两个规则:  /./  代表不变
                  /../   代表返回上级目录
还有就是Corner Cases中的特殊情况都有说明
 
 
这道题刚开始写了好半天,其实主要原因是,题目中有一个没有说明,那就是带有转义字符的情况:如果目录名字中含有‘/’,如果考虑这种情况会复杂许多。但是这道题其实没有考虑这种情况,也就是说将\这个符号当成一般的字符处理。所以也就没什么难点,就是考虑清楚情况。
可以使用自动机求解。
public class Solution {
    public String simplifyPath(String path) {
        int len = path.length();
        if (len == 0)
            return path;
        Stack<Character> stack = new Stack<Character>();
        int i = 0;
        while (i < len) {
            if (path.charAt(i) == '/') {
                while( i<len && path.charAt(i) == '/')
                        i++;
                i--;
                if( i+1 == len)
                    i++;
                else if( path.charAt(i+1) == '.'){
                    if( i+2 == len || path.charAt(i+2) == '/')
                        i+=2;
                    else if( path.charAt(i+2) == '.'){
                        if( i+3 == len || path.charAt(i+3) == '/'){
                            int j = 0;
                            
                            while( j<stack.size() )
                                if(  stack.pop() == '/')
                                    break;
                                j++;
                            
                            i+=3;
                        }else{
                            stack.push('/');
                            stack.push('.');
                            stack.push('.');
                            i+=3;
                            while (i < len) {
                                if (path.charAt(i) == '/')
                                    break;
                                else 
                                    stack.push(path.charAt(i));
                                i++;
                            }
                        }
                    }else{
                        stack.push('/');
                        stack.push('.');
                        i+=2;
                        while (i < len) {
                            if (path.charAt(i) == '/')
                                break;
                            else 
                                stack.push(path.charAt(i));
                            i++;
                        }
                    
                    }
                        
                }else{
                    i++;
                    stack.push('/');
                    
                    while (i < len) {   
                        if (path.charAt(i) == '/')
                            break;
                        else 
                            stack.push(path.charAt(i));
                        i++;
                    }
                }
            } else {
                if( path.charAt(i) == '.'){
                    if( i+1 == len || path.charAt(i+1) == '/')
                        i+=2;
                    else if( i+2 == len || (path.charAt(i+1) == '.' && path.charAt(i+2) == '/'))
                        i+=3;
                }else{
                    stack.push('/');
                while (i < len) {
                    if (path.charAt(i) == '/')
                        break;
                    else 
                        stack.push(path.charAt(i));
                    i++;
                }
                }
                
                stack.push('/');
                while (i < len) {
                    if (path.charAt(i) == '/')
                        break;
                    else 
                        stack.push(path.charAt(i));
                    i++;
                }
            }
            
        }
        len = stack.size();
        if( len == 0)
            return new String("/");
        char[] result = new char[len];
        for (int j = len - 1; j >= 0; j--) {
            result[j] = stack.pop();
        }
        return String.valueOf(result);

    }
}