LeetCode刷题笔记--71. Simplify Path

71. Simplify Path

Medium

4081140FavoriteShare

Given an absolute path for a file (Unix-style), simplify it. Or in other words, convert it to the canonical path.

In a UNIX-style file system, a period . refers to the current directory. Furthermore, a double period .. moves the directory up a level. For more information, see: Absolute path vs relative path in Linux/Unix

Note that the returned canonical path must always begin with a slash /, and there must be only a single slash / between two directory names. The last directory name (if it exists) must not end with a trailing /. Also, the canonical path must be the shortest string representing the absolute path.

Example 1:

Input: "/home/"
Output: "/home"
Explanation: Note that there is no trailing slash after the last directory name.

Example 2:

Input: "/../"
Output: "/"
Explanation: Going one level up from the root directory is a no-op, as the root level is the highest level you can go.

Example 3:

Input: "/home//foo/"
Output: "/home/foo"
Explanation: In the canonical path, multiple consecutive slashes are replaced by a single one.

Example 4:

Input: "/a/./b/../../c/"
Output: "/c"

Example 5:

Input: "/a/../../b/../c//.//"
Output: "/c"

Example 6:

Input: "/a//b////c/d//././/.."
Output: "/a/b/c"

这道题我放到VS里调了多次才一步一步最终接近答案,test case太多太恶心。

比如这样的testcase:

真的是试了很多遍才试出来,不怕麻烦的可以自己尝试着做做。

下面说一下整理路径的策略(这个题目里写的不够清楚,直接导致了这么多次提交错误):

1.首先需要搜集路径,从左到右搜集,放到一个数组中ans

2.在搜集路径过程中,如果遇到/../或者/..(结束),需要从数组ans中弹出一个路径(pop_back)

3.在搜集路径过程中,如果遇到/.../或者/...(结束),需要把...加入到ans中(这一点很难想到,要出错了才知道)

4.除了路径以外的内容统统先扔掉

5.得到路径数组以后,把/加上去,拼出答案k

下面是AC的答案,判断条件中的边界需要特别注意,很容易出错,还有a溢出的问题,有个地方是需要a--还原的:

class Solution {
public:
    string simplifyPath(string path) {
        int a = 0;
        //int b=0;
        vector<string> ans;
        ans.clear();

      

        //下面开始记录路径数组

        for (; a < path.length(); a++)//从第一个字母开始,从左到右挨个过滤
        {
            if (path[a] != '/'&&path[a] != '.')//第一种情况:如果是字母
            {
                string tempStr = "";
                while (a < path.length() && path[a] != '/'&&path[a] != '.')//从第一个字母开始把一串没被/分开的字符串记录下来,直到下一个/或者.
                {
                    tempStr += path[a];
                    a++;
                }
                a--;//此时a已经指向/,需要倒回去一位
                ans.push_back(tempStr);//将这个字符串压入数组
            }
            else if (path[a] == '/')//第二种情况:如果是/
            {

              //去掉的第一种情况是/./或者/.(结束)
                if ((a + 2 < path.length() && path[a + 1] == '.'&&path[a + 2] == '/') || (a + 2 == path.length() && path[a + 1] == '.'))a++;
                 //去掉的第二种情况是/../或者/..(结束)

              else if ((a + 3 < path.length() && path[a + 1] == '.'&&path[a + 2] == '.'&&path[a + 3] == '/') || (a + 3 == path.length() && path[a + 1] == '.'&&path[a + 2] == '.'))
                {
                    a = a + 2;
                    if (ans.size() >= 1)ans.pop_back();
                }

               //保留...
                else if(a + 1 < path.length() && path[a + 1] == '.')
                {
                    string tempStr = "";
                    a++;
                    while (a < path.length() && path[a] != '/')
                    {
                        tempStr += path[a];
                        a++;
                    }
                    a--;
                    ans.push_back(tempStr);
                }
            }
        }

        string k = "/";
        if (ans.size() == 0)return "/";
        for (int p = 0; p < ans.size() - 1; p++)
        {
            k += ans[p];
            k += "/";
        }
        k += ans[ans.size() - 1];

        //if (k.length() == 0)k = "/";
        return k;
    }
};

猜你喜欢

转载自blog.csdn.net/vivian0239/article/details/89880668