题目

给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。

在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。

请注意,返回的 规范路径 必须遵循下述格式:

  • 始终以斜杠 '/' 开头。
  • 两个目录名之间必须只有一个斜杠 '/' 。
  • 最后一个目录名(如果存在)不能 以 '/' 结尾。
  • 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。

返回简化后得到的 规范路径 。

来源:力扣(LeetCode)


解答

通过Go的字符串分割,按"/"分割即可,C++的话可以使用stringstream进行分割。

然后对分割后的每一部分路径(即文件夹名)进行分析,特殊的如果是".",就不进行路径保存,如果是".."表示上级目录,就将当前保存的最后一个目录删除(且保证有内容可以删除)。

最后将保存的目录结构统一输出,并以"/"进行连接即可。

代码如下:

Go

func simplifyPath(path string) string {
	var ret []string

	get := strings.Split(path, "/")
	for _, v := range get {
		if v == "." {
			continue
		} else if v == ".." {
			if len(ret) > 0 {
				ret = ret[:len(ret)-1]
			}
		} else if v != "" {
			ret = append(ret, v)
		}
	}

	return "/" + strings.Join(ret, "/")
}

C++

class Solution {
public:
    string simplifyPath(string path) {
        stringstream ss(path);
        string tmp;
        vector<string> rc;
        string ret;

        while (getline(ss, tmp, '/')) {
            if (tmp == ".") {
                continue;
            } else if (tmp == "..") {
                if (!rc.empty()) {
                    rc.pop_back();
                }
            } else if (!tmp.empty()) {
                rc.push_back(tmp);
            }
        }

        for (auto &i: rc) {
            ret += "/" + i;
        }
        
        if (ret.empty()) {
            return "/";
        }

        return ret;
    }
};