题目描述
某简易的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;
}