[LintCode] Simplify Path [字符串操作]

361 查看

Problem

Given an absolute path for a file (Unix-style), simplify it.

Example

"/home/", => "/home" //去掉末尾的slash

"/a/./b/../../c/", => "/c" //每个"/../"对应:删除一个上层的segment

Challenge

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".

Note

关于challenge的两点:

  1. "/../",这里讨论的有两种情况,空集和"/../"本身。空集加一个if语句返回slash就可以了,"/../"本身要综合Example的例子,pop出上一层元素。

  2. Multiple slashes,可以用split()函数去掉所有slash,然后多考虑一个slash中间为空的case。

关于switch语句的一个特点:

我们对case ""和case "."其实都是不做操作,然而,两个case可以都break,但是不能都不做操作。像这样:

case "":
case ".":

这样这两个case就都会等价于下一个case:case "..". 就会出错。

Solution

public class Solution {
    public String simplifyPath(String path) {
        Stack<String> stack = new Stack<String>();
        String[] segments = path.split("/");
        for (String segment: segments) {
            switch(segment) {
                case "": break;
                case ".":
                case "..": 
                    if (!stack.isEmpty()) {
                        stack.pop();
                    }
                    break;
                default: stack.push(segment);
            }
        }
        StringBuilder sb = new StringBuilder();
        if (stack.isEmpty()) {//空集的情况
            return "/";
        }
        while (!stack.isEmpty()) {
            sb.insert(0, "/"+stack.pop());//Don't miss the slash!
        }
        return sb.toString();
    }
}