题目描述
基本思路
基本步骤
如下图所示,路径的规范化可分为三部分:
- 第一部分(ext)是从路径字符串中解析出文件、文件夹、"..",并按照路径字符串中出现的先后顺序存储在数组sl中;
- 第二部分(arrange)将sl数组进行整理,去掉"..",使其符合绝对路径要求,结果存入resl;
- 第三部分(getR)将resl中的文件或文件夹按顺序连成路径。
ext实现思路
函数参数:路径字符串str,文件空数组sl。
(1) 首先将st拷贝到s,在s最后添加一个’/’(这样处理起来更加方便)。
(2) 声明一个空字符串s0。
(3) 遍历字符串,对于每一个字符:
- 如果不是’/’,将这个字符添加到s0末尾;
- 否则,如果s0是".",将s0清空(因为"."是冗余信息);如果s0是空字符串,则跳过本轮,继续遍历;否则,将s0添加到数组最后,数组元素个数加1,清空s0。
arrange实现思路
函数参数:文件数组sl,sl元素个数c,文件空数组resl,路径字符串首字符firc。
全局变量:相对路径文件数组curl,及其元素个数n(这两个变量通过ext解析相对路径字符串得到)。
(1) 判断当前路径是绝对路径还是相对路径(firc是不是’/’)。
(2) 如果是绝对路径,遍历数组sl,利用虚拟指针p将数组sl中的文件或文件夹拷贝到resl中,如果遇到了"..",则p = max(0,p-1),继续遍历。
(3) 如果是相对路径,首先将curl中的元素拷贝到resl中,然后按照(2)的方法,将数组sl中的文件或文件夹拷贝到resl中。
getR实现思路
将resl数组中的字符串连起来,两两之间添加’/'即可。如果resl中没有元素,那么直接返回"/"。
reg实现思路
函数参数:路径字符串s。
首先,判断s是不是"",如果是,规范化结果为"/";
否则,通过ext,arrange,getR即可得到规范化路径字符串。
遇到的坑
关同步ios::sync_with_stdio(false)
可以提高cin,cout的读写效率,但是在使用getchar的情况下,不能够再关同步。
完整代码
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
string curr;
string curl[1005];
int n;
int N;
int ext(const string &str, string sl[]) //从路径字符串中提取文件或文件夹名
{
int c=0;
string s = str+"/";
string s0="";
for(int i=0,l=s.length();i<l;i++)
{
if(s[i]=='/')
{
if(s0 == ".") s0="";
else if(s0 != "") sl[c++]=s0, s0="";
continue;
}
s0.push_back(s[i]);
}
return c;
}
int arrange(string sl[], int c, string resl[], char firc)
{
int p;
if(firc == '/')
{
p=0;
for(int i=0;i<c;i++)
{
if(sl[i] == "..") p = max(0, p-1);
else resl[p++]=sl[i];
}
}
else
{
for(int i=0;i<n;i++) resl[i] = curl[i];
p=n;
for(int i=0;i<c;i++)
{
if(sl[i] == "..") p = max(0, p-1);
else resl[p++]=sl[i];
}
}
return p;
}
string getR(string sl[], int c) //给一个文件数组,把它连成路径
{
if (c==0) return "/";
string s="";
for(int i=0;i<c;i++)
{
s.push_back('/');
for(int j=0, l=sl[i].length();j<l;j++) s.push_back(sl[i][j]);
}
return s;
}
string reg(const string &s)
{
if(s=="") return curr;
string sl[1005];
int c = ext(s, sl);
string resl[1005];
int p = arrange(sl, c, resl, s[0]);
return getR(resl, p);
}
int main ()
{
// ios::sync_with_stdio(false); 用了getchar,不能关同步
cin>>N;
getchar();
cin>>curr;
getchar();
n = ext(curr, curl);
for(int i=0;i<N;i++)
{
string s="";
char c;
while((c=getchar())!='\n') s.push_back(c);
cout<<reg(s)<<endl;
}
return 0;
}