CCF认证2016043-路径解析

本人初学,水平有限,若有不足,恳请赐教!

目录

1 方法1

2 方法2


这道题实际上并不是很难,然而我做了一个下午。其实我的思路并没有什么问题,主要问题出现在两处,一处是忽略的输入为空串代表当前目录的条件,另一处是被题目的样例输入误导了……这里我提供了一个比较全面的测试用例供大家使用。

9
/d2/d3
./d1/d2/

../d4/f1
/d1/./f1
./d1///f1
/d1/
///../../../../
/d1/../../d2
d1/

可以发现我提供的测试用例包括了两种题目输入样例没有包含的情况,一个空串,另一个则是以一个非根目录的目录开头的路径(就因为没有考虑到这种情况我的得分一直都是80TT)。

1 方法1

对所有的路径做分割处理,将分割后的字符串存入数组。根据数组首个元素的内容来判断此路径是接着当前路径的相对路径还是绝对路径。然后在根据其他元素内容来对结果数组做入栈或出栈操作。

具体代码如下:

#include <iostream>
#include <string>
#include <vector>
#include <regex>

using namespace std;

void split(string s, vector<string> &path) //按斜线分割字符串并存入数组中
{
	if(s == "") return;
	s = regex_replace(s, regex("/+"), "/"); //将多个斜线替换为一个斜线
	if(s.back() == '/' && s.size() > 1) s.pop_back(); //去除尾部斜线
	for(int i = 0, j; i < s.size(); i = j)
	{
		j = s.find('/', i); //从字符串的第i位开始查找斜线并返回位置
		path.push_back(s.substr(i, j - i)); //将满足条件的存入数组
		if(j == s.npos) break;
		else j++;
	}
}

int main()
{
	//FILE *stream;
	//freopen_s(&stream, "data.txt", "r", stdin);

	int n;
	cin >> n;
	getchar();
	string curs; //记录当前工作目录
	getline(cin, curs);
	vector<string> curp;
	split(curs, curp);
	while(n--)
	{
		string s;
		getline(cin, s); //注意cin无法读取空串
		vector<string> input;
		split(s, input);
		vector<string> ans;
		//输入路径不是斜线开头或者输入为空串说明是接着当前工作目录的路径
		if(input.empty() || input[0] != "") ans = curp;
		for(unsigned i = 0; i < input.size(); i++)
		{
			if(input[i] == ".." && ans.size() > 1) ans.pop_back(); //对非根目录的..操作需要出栈
			else if(input[i] == ".." && ans.size() == 1) continue; //对根目录的..操作仍是根目录,故不变
			else if(input[i] != ".")ans.push_back(input[i]);
		}
		for(unsigned i = 0; i < ans.size(); i++)
		{
			if(i == 0) cout << "/";
			else if(i == 1) cout << ans[i];
			else cout << "/" << ans[i];
		}
		cout << endl;
	}

	//fclose(stream);

	return 0;
}

2 方法2

 这个方法是我从其他博主那里参考的,这个方法巧妙地使用了sstream来分割字符串,相比于方法1大大地削减了代码量。

具体代码如下:

#include <iostream>
#include <vector>
#include <regex>
#include <sstream>

using namespace std;

int main()
{
	//FILE *stream;
	//freopen_s(&stream, "data.txt", "r", stdin);

	int n;
	cin >> n;
	string curs; //记录当前工作目录
	cin >> curs;
	getchar();
	for(int i = 0; i < n; ++i)
	{
		string path;
		getline(cin, path);
		//输入路径不是斜线开头或者输入为空串说明是接着当前工作目录的路径
		if(path == "" || path[0] != '/') path = curs + '/' + path;
		//将路径中所有的斜线全替换为空格,这样在作为输入流时可以自动将各个目录或文件分割
		path = regex_replace(path, regex("/"), " ");
		vector<string> ans;
		stringstream ss(path);
		string s;
		while(ss >> s)
		{
			if(s == ".." && !ans.empty()) ans.pop_back();
			else if(s == ".." && ans.empty()) continue;
			else if(s != ".") ans.push_back(s);
		}
		cout << '/';
		for(int j = 0; j < ans.size(); ++j)
		{
			if(j) cout << '/';
			cout << ans[j];
		}
		cout << endl;
	}

	//fclose(stream);

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值