题目描述
(刚看到这个题的时候,我的脑子是蒙的,不知道他要让我们干啥,后来发现这跟Linux还是有点关系的)以下是思路(虽然很长,但是牛人的解法很容易理解):
1、/表示根目录,linux/uinx下目录是成树结构的,根目录即树的根,不可能再继续向上了。
2、. 表示当前目录。
3、… 表示上级目录。
4、/也用于目录间的分隔,如/a/b 表示根目录下的a路径下的b路径;a/b 表示当前目录下的a路径下的b路径。
5、/用于分隔符号时,个数可多可少,如//a/////b和/a/b是一样的。注意//a/////b和a/b不一样,因为前者有个根目录。结尾的/无意义,如a/b和a/b/是一样的。
我们可以用入栈出栈来模拟进入目录退出目录,但是stl 的stack又不适用,因为stack只能从栈顶依次输出,处理笔记麻烦,所以用vector。一个临时变量ret,用于保存两个/ 之间的字符串。
1、如果ret == "."什么也不做
2、如果ret == "…"出栈
3、否则,ret入栈。
需要注意的地方:
1、出栈前要判断栈不为空,因为在linux、unix下,命令 cd /…/…/是合法的,结果是进入根目录,不可能在向上了。
2、入栈前要判断str是否是空字符串,因为要排除类似//a/////b的这种情况。
3、最后结果中,如果栈是空的,也要输出一个 /
代码:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <stack>
#include <vector>
#include <math.h>
using namespace std;
//简化Uinx风格的路径
int main()
{
string str;
while (cin>>str)
{
int i = 0;
int j = 0;
string ret;
vector<string> s;
vector<string> ::iterator it;
for (i = 0; i < str.size(); i++)
{
if (str[i] == '/')
{
j = i + 1;
while (j<str.size()&&str[j] != '/')
{
j++;
}
if (i + 1 < str.size())
{
ret = str.substr(i + 1, j - i - 1);
if (ret == "..") //出栈前判断是否为空
{
if (!s.empty())
{
s.pop_back();
}
}
else if (ret == ".")
{
; //什么也不做
}
else if (!ret.empty()) //入栈之前看其截取的是否为空
{
s.push_back(ret);
}
}
}
i = j - 1;
}
if (s.empty()) //如果是空的就输出"/"
{
cout << "/" << endl;
}
else
{
for (it = s.begin(); it != s.end(); ++it)
{
cout << "/" << *it << endl;
}
}
}
system("pause");
return 0;
}
结果截图:
我觉得这个题蛮有意思的,先记录下来