力扣71. 简化路径(栈、字符串)C++

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

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

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

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

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

示例 1:

输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。 

示例 2:

输入:path = "/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。

示例 3:

输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。

示例 4:

输入:path = "/a/./b/../../c/"
输出:"/c"

提示:

  • 1 <= path.length <= 3000
  • path 由英文字母,数字,'.''/' 或 '_' 组成。
  • path 是一个有效的 Unix 风格绝对路径。

 

class Solution {
public:
    // 函数 simplifyPath 用于简化 Unix 风格的路径
    string simplifyPath(string path) {
        // 定义一个 lambda 函数 split,它接受一个字符串和一个分隔符,返回一个由分隔符分割的字符串向量
        auto split = [](const string& s, char delim) -> vector<string> {
            vector<string> ans; // 初始化一个空的字符串向量用于存放分割后的子字符串
            string cur; // 当前子字符串
            // 遍历输入字符串的每个字符
            for (char ch : s) {
                // 如果当前字符等于分隔符,则将当前子字符串添加到 ans 中,并清空当前子字符串
                if (ch == delim) {
                    ans.push_back(move(cur));
                    cur.clear();
                } else {
                    // 否则将当前字符添加到当前子字符串中
                    cur += ch;
                }
            }
            // 将最后一个子字符串(如果存在)添加到 ans 中
            ans.push_back(move(cur));
            return ans; // 返回分割后的字符串向量
        };

        // 使用 split 函数按 '/' 分割路径字符串
        vector<string> names = split(path, '/');
        // 用一个 vector 作为栈来存储路径的每个部分
        vector<string> stack;

        // 遍历分割后的路径的每个部分
        for(string& name:names){
            // 如果部分是 "..",则从栈中弹出最后一个元素,模拟返回上级目录
            if(name==".."){
                if(!stack.empty())
                stack.pop_back();
            }
            // 如果部分不是空字符串也不是 ".",则将其添加到栈中
            else if(!name.empty()&&name!=".")
                stack.push_back(name);
        }

        string ans; // 用于存放简化后的路径
        // 如果栈为空,则返回根目录 "/"
        if (stack.empty()) {
            ans = "/";
        } else {
            // 否则,遍历栈中的每个元素,构造简化后的路径
            for(string& name:stack){
                ans+="/"+move(name);
            }
        }
        return ans; // 返回简化后的路径
    }
};

这段代码的思路如下:

  1. 首先定义了一个 lambda 函数 split,用于将字符串按照指定的分隔符分割成子字符串,并存放在一个字符串向量中。

  2. 使用 split 函数将输入的路径字符串按照 "/" 分割成多个子字符串,并存放在 names 向量中。

  3. 创建一个 stack 向量,用于模拟栈来存储路径的每个部分。

  4. 遍历分割后的路径的每个部分,在遍历过程中进行以下逻辑判断:

    • 如果当前部分是 "..",则表示返回上级目录,从栈中弹出最后一个元素。
    • 如果当前部分不是空字符串且不是 ".",则将其添加到栈中。
  5. 构造一个空的字符串 ans 用于存放简化后的路径。

  6. 如果栈为空,则表示路径是根目录,将根目录的符号 "/" 添加到 ans 中。

  7. 否则,遍历栈中的每个元素,将其添加到 ans 中,并在每个元素前面添加一个 "/"。

  8. 返回简化后的路径 ans。

 

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值