问题描述
输入输出
样例
规定
思路
要求出每条路径正规化后的样子,已知当前目录cur,各路径独立、互不影响。
根据题意,正规化需要的操作如下:
- 找到去除“/…”,并将路径返回上一级目录
- 找到直接去除“/.”,路径依然在本目录
- 对于连续多个/符号,只保留一个
- 去除结尾的/
依次对P条路径进行操作。
- 首先判断一条路径是否为空字符串,若是,赋予它当前目录。
- 然后判断该路径是绝对路径还是相对路径,如果是相对路径,在这条路径前添加当前目录形成新的绝对路径。
- 下一步进行正规化。对于操作1,“/…/”如果在开头,直接删除(根目录的上一级仍是根目录);如果在中间,找到“/…/”前的那个目录,需要用rfind()从后往前查找,将两者一同删除。
- 接下来进行操作2、3、4,操作2、3都是找到就直接删除;操作4删除结尾的’/‘之前,要先保证当前字符串长度大于1,字符串变为除了最后的’/'外剩余的子串。
注意
- 输入路径s时,若s为空字符串会因为无法识别而直接忽略,因此要用getline()获取路径s。
- 要用getchar()提前将输入当前路径cur时的回车取走。
代码
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
string cur,s;
int p;
int main() {
cin>>p;
cin>>cur;getchar();
while(p--) {
getline(cin,s);
if(s.empty()) s=cur;
else if(s[0]!='/') s=cur+'/'+s;//化为绝对路径
int i,j;
while((i=s.find("/../"))!=-1) {
if(i==0) s.erase(0,3);
else {
j=s.rfind("/",i-1);//从i反向搜索
s.erase(j,i-j+3);
}
}
while((i=s.find("/./"))!=-1)
s.erase(i,2);
while((i=s.find("//"))!=-1)
s.erase(i,1);
if(s.size()>1&&s[s.size()-1]=='/')
s=s.substr(0,s.size()-1);
cout<<s<<endl;
}
return 0;
}