CSP 201604-3路径解析
问题描述
输入格式
第一行包含一个整数 P,表示需要进行正规化操作的路径个数。
第二行包含一个字符串,表示当前目录。
以下 P 行,每行包含一个字符串,表示需要进行正规化操作的路径。
输出格式
共 P 行,每行一个字符串,表示经过正规化操作后的路径,顺序与输入对应。
样例输入
7
/d2/d3
/d2/d4/f1
…/d4/f1
/d1/./f1
/d1///f1
/d1/
///
/d1/…/…/d2
样例输出
/d2/d4/f1
/d2/d4/f1
/d1/f1
/d1/f1
/d1
/
/d2
评测用例规模与约定
1 ≤ P ≤ 10。
文件和目录的名字只包含大小写字母、数字和小数点 .、减号 - 以及下划线 _。
不会有文件或目录的名字是 . 或 … ,它们具有题目描述中给出的特殊含义。
输入的所有路径每个长度不超过 1000 个字符。
输入的当前目录保证是一个经过正规化操作后的路径。
对于前 30% 的测试用例,需要正规化的路径的组成部分不包含 . 和 … 。
对于前 60% 的测试用例,需要正规化的路径都是绝对路径。
题意:
将所有的路径正规化。
分析:
通过读题可以明确以下两个概念:
绝对路径:以 / 符号开头,表示从根目录开始构建的路径。
相对路径:不以 / 符号开头,表示从当前目录开始构建的路径。
对于这两类情况,第一步应该判断是不是相对路径,即判断第一个字符是不是"/"。如果是相对路径,则把当前路径加在相对路径头部,就形成了一个绝对路径。紧接着是对绝对路径的处理,只需要主义以下四个方面:
存在连续多个"/“需要只输出一个
结尾的”/“需要删除
出现”.“时需要删除;
出现”…“时,如果在它之前没有其他项了,和处理”."一样删除即可。否则删除它和它前面一项。
对于每一条需要正规化的路径,使用一个vector存储,只存储每一项路径而不存储"/"。输出时再在每一项之前先输出"/"。
代码如下:
#include<iostream>
#include<string>
#include<string.h>
#include<vector>
using namespace std;
int main()
{
int p;
string s1, s2;
vector<string> s[20];
cin >> p;
cin >> s1;
cin.ignore();
for (int i = 0; i < p; i++)
{
getline(cin, s2);
if (s2[0] != '/')
s2 = s1 + "/" + s2;
string t = "";
int flag = 1;
for (int j = 1; j <= s2.size(); j++)
{
if (s2[j] == '/' || j == s2.size())
{
if (flag == 0)
{
flag = 1;
s[i].push_back(t);
t.clear();
}
else
continue;
}
else
{
flag = 0;
t += s2[j];
}
}
}
for (int i = 0; i < p; i++)
{
for (int j = 0; j < s[i].size();)
{
if (s[i][j] == "..")
{
if (j > 0)
{
j--;
s[i].erase(s[i].begin() + j);
s[i].erase(s[i].begin() + j);
}
else
s[i].erase(s[i].begin() + j);
}
else if (s[i][j] == ".")
s[i].erase(s[i].begin() + j);
else
j++;
}
}
for (int i = 0; i < p; i++)
{
if (s[i].size() == 0)
cout << "/";
else
{
for (int j = 0; j < s[i].size(); j++)
{
cout << "/";
if (j < s[i].size())
cout << s[i][j];
}
}
cout << endl;
}
return 0;
}