题意:
在文件系统中,有几种文件的查找方式。分为绝对路径和相对路径。根目录为“/”,其余子目录分别跟在其根目录的后面。同时在相邻的两部分之间用“/”隔开。同时在其中有“…”表示上一级目录。“.”表示当前目录。如果有多个“/”时,只需要用一个就可以,在末尾的“/”也需要删去,最后形成一个正规化操作的后的路径。
input:
第一行为一个数P,(P<=10)为需要正规化操作的路径个数。第二行是当前所在的路径。余下的P行是需要正规化的路径,其中每一行的的字符长度不超过1000个字符。
output:
依次输出每个正规化的路径,注意如果是一个空行的时候,则输出当前所在的路径。
思路:
首先读取当前地址。用一个string数组P依次保存每一个层次的地址名称。即遍历每一个字符,当遇到“/”,P[i+1],即为继续保存下一个层次的地址。否则当前的地址P[i]+=p[j],即继续将这个字符保存在当前的string中。在保存完当前的地址记录后,读取每一行记录,判断出如果是一个空行的话,直接输出当前的地址。
如果不是空行的话,根据首字符,如果是“/”,则为绝对地址,否则首先为相对地址,则先将当前的地址保存到要输出的string数组中,即先来到当前的地址。剩下的和保存当前地址相似,依次读出每一个字符。将连续的字符依次保存在相同的string中,直到读到“/”,在读到“/”的时候,判断当前string中记录的,如果是“…",并且t>0,则返回上一层,即t–。遇到“/”时,判断当前的string,如果长度>0,即说明其中有路径名,并且该路径名不是“.”和“…”时,t++。进入下一个字符。注意空行的处理,一开始直接用的cin,导致空行读不进去,后来用的getline(cin,s),即每次直接读一行,再根据读取的这个string的长度来判断是否是空行。
代码:
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int N;
string P[500]; //记录当前的地址
int n = 0; //当前地址个数
string tmp[500]; //记录当前需要正规化的地址
string T; //依次保存每一个合法的地址
string p; //读取一行地址
int main() {
cin >> N;
getchar();
char c;
c = getchar();
while (c != '\n') { //保存当前的地址
if (c != '/') {
P[n] += c;
}
else {
n++;
}
c = getchar();
}
for (int k = 0; k < N; k++) {
getline(cin, p);
if (p.length() == 0) { //空行,输出当前的地址
for (int i = 1; i <= n; i++) {
cout << "/" << P[i];
}
cout << endl;
continue;
}
else {
int t = 0; //记录已经记录多少个地址数
if (p[0] != '/'){
t = n;
for (int i = 1; i <= n; i++) { //首先到当前地址
tmp[i - 1] = P[i];
}
}
for (int i = 0; i < p.length(); i++) {
if (p[i] != '/') {
T += p[i];
}
else {
if (T == ".." && t > 0) {
t--;
}
else if (T.length() != 0 && T != "." && T != "..") {
tmp[t] = T;
t++;
}
T.clear();
}
}
if (T.length() != 0) { //保存下最后一个地址
tmp[t] = T;
t++;
T.clear();
}
if (t == 0) { //输出地址,
cout << "/";
}
else {
for (int i = 0; i < t; i++) {
cout << "/" << tmp[i];
}
}
cout << endl;
}
}
return 0;
}