71. Simplify Path

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

For example, path = "/home/", => "/home" path = "/a/./b/../../c/", => "/c" path = "/a/../../b/../c//.//", => "/c" path = "/a//b////c/d//././/..", => "/a/b/c"

In a UNIX-style file system, a period ('.') refers to the current directory, so it can be ignored in a simplified path. Additionally, a double period ("..") moves up a directory, so it cancels out whatever the last directory was. For more information, look here: https://en.wikipedia.org/wiki/Path_(computing)#Unix_style

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

思路

分析题目的意思,以及结合linux下目录方法,可得:

  • . 代表当前目录,可忽略
  • .. 代表上一级目录,应退到前一个 /
  • // 合并为 /
  • 末尾/删除

对路径字符串以 / 进行切割,然后将切割后的字符串进行入栈和出栈操作。

/a/./b/../../c/ 为例:

分割后结果如下

a  .  b  ..  ..  c
character action stack
a push a
. ignore a
b push a b
.. pop a
.. pop
c push c

最后将结果补充上 / 即可:/c.

逻辑就是:

  • 遇到 ., 空字符串这两种情况,continue。
  • 遇到 .. ,分两种情况:
    • 若 stack 不为空的话,pop 操作;
    • 若stack为空,则continue。
  • 其他字符串执行 push 操作。

代码

class Solution {
public:
    string simplifyPath(string path) {
        vector<string> stack;
        string res, tmp;
        istringstream iss(path);
        while (getline(iss, tmp, '/')) {
            if (tmp == "." || tmp == "") continue;
            else if (tmp == "..") 
                if (stack.empty()) continue; else stack.pop_back();
            else stack.push_back(tmp);
        }
        for (auto str : stack) res += '/' + str;
        return res.empty() ? "/" : res;
    }
};

results matching ""

    No results matching ""