刷题-简易Linux路径解析

题目描述

某简易的linux目录系统 cd 命令(change directory)功能如下:

  • cd :进入home目录/home/user
  • cd -:进入上一次停留的目录(连续两个以上 cd - 会在两个目录之间来回跳转,而不是回到更早之前的目录);
  • cd <绝对路径>:以 / 开头的为绝对路径;
  • cd <相对路径>:不以/开头的为相对路径;

现给定一批 cd 命令,命令格式及相关假设如下:

  • 单独的/表示根目录,且为系统默认的初始目录;
  • a表示目录/a,即这种格式中的多个 / 等价于一个 / ;
  • 特殊目录. ,表示当前层次目录,例如/a/. 表示目录/a
  • 特殊目录..,表示当前层次目录的父目录(根目录的父目录仍为根),例如/a/..表示目录/
  • 假设不会出现第一个命令为cd -的情况;

请计算所有命令执行结束后的最终目录,并格式化输出其绝对路径:

  • 必须以/开头,不以/结尾(除根目录外);
  • 不允许特殊目录...,不允许连续的/,需转化为所表示的目录;

解答要求时间限制:1000ms, 内存限制:128MB

输入

首行一个整数 n,表示 cd 命令的个数,取值范围:[1,100]
接下来 n 行,每行一条 cd 命令,长度范围 [1, 100],其中目录名仅由小写英文字母 [a-z] 组成

假设:

  • 设目录总长度 < 10000
  • 命令中的目录都是存在的
  • 命令格式都符合规则

输出

一个字符串,表示最终目录的绝对路径。

样例

输入样例 1 

3
cd /aa/bb/cc/dd/
cd ./ee/ff
cd gg/../hh

输出样例 1

/aa/bb/cc/dd/ee/ff/hh

提示样例 1

默认目录在 / ,各条命令执行情况如下:

  • 第一条:路径名以 / 开头表示绝对路径,执行后当前目录为 /aa/bb/cc/dd/
  • 第二条:路径名不以 / 开头表示相对路径,进入当前目录的下层目录,执行后当前目录为 /aa/bb/cc/dd/ee/ff
  • 第三条:路径名不以 / 开头表示相对路径,gg/../hh 表示先进入下层目录 gg,接着返回 gg 的上层目录即当前目录,然后进入下层目录 hh, 因此最终目录为 /aa/bb/cc/dd/ee/ff/hh


 

输入样例 2 

2
cd
cd ..

输出样例 2

/home

提示样例 2

第一条:进入home目录 /home/user
第二条:进入当前目录的父目录即 /home


 

输入样例 3 

3
cd /aabb//
cd ..
cd -

输出样例 3

/aa/bb

提示样例 3

第一条:多个 / 等价于一个,当前目录为 /aa/bb
第二条:进入父目录后当前目录为 /aa,上一次停留的目录为 /aa/bb
第三条:进入上一次停留的目录,最终目录为 /aa/bb

解题代码


#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;

class Solution {
public:
     void SubCurPath()
    {
        int index = curPath.find_last_of('/');
        if (index != -1)
            curPath.erase(index, curPath.size()-index);
    }

    void Process(string str)
    {
        if (str == "cd") {
            lastPath = curPath;
            curPath = "/home/user";
            return;
        }

        //取出路径字符串
        string path = str.substr(3, str.size()-3);
        if (path == "-") {
            string tmp = lastPath;
            lastPath = curPath;
            curPath = tmp;
            return;
        } else {
            lastPath = curPath;
        }

        //绝对路径, 先回到根目录
        if (path[0] == '/') { 
            lastPath = curPath;
            curPath = "";
        } 

        vector<string> sPath;
        stringstream ss(path);
        string p;
        while(getline(ss, p, '/')) {
            //去掉空串
            if (p == "")
                continue;
            sPath.push_back(p);
        }

        for (string s : sPath) {
            if (s == ".") {
                continue;
            }
            else if (s == "..") {
                SubCurPath();
            } else {
                curPath += ("/" + s);
            }
        }
    }
    string GetCurrentDirectory(const vector<string>& cmds)
    {
        if (cmds.size() == 0) {
            return "";
        }

        for (string s:cmds) { 
            Process(s);
        }

        if (curPath.size() == 0)
            curPath = "/";
        return curPath;
    }
private:
    string curPath;
    string lastPath;
};

int main()
{
    string line;
    getline(cin, line);
    int num = stoi(line);
    vector<string> cmds;
    for (int loop = 0; loop < num; loop++) {
        getline(cin, line);
        cmds.push_back(line);
    }
    Solution parser;
    cout << parser.GetCurrentDirectory(cmds) << endl;
    return 0;
}

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值