csp 201604-3 路径解析

本文详细解析了文件系统中路径规范化的算法实现,包括绝对路径和相对路径的处理,通过字符串数组保存各层次地址,以及如何正确处理特殊符号如'.'和'..',并提供了完整的C++代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

在文件系统中,有几种文件的查找方式。分为绝对路径和相对路径。根目录为“/”,其余子目录分别跟在其根目录的后面。同时在相邻的两部分之间用“/”隔开。同时在其中有“…”表示上一级目录。“.”表示当前目录。如果有多个“/”时,只需要用一个就可以,在末尾的“/”也需要删去,最后形成一个正规化操作的后的路径。

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值