【CCF 201604-3】路径解析

大致思路

①预处理当前目录

将当前目录的路径都保存在一个vector<string> vec_cur中:将"/"替换为" ",然后用字符串流即可

②预处理给定目录

1.将"//"全部删除,将"/./"替换为"/"

2.若给定目录为绝对路径:类似于①中方法将路径保存至vector<string> path中,其中遇到".."时将vector的最后一个元素删除即可;

若给定目录为相对路径,令path = vec_cur,再将其当做绝对路径处理。

C++满分代码

#include <iostream>
#include <vector>
#include <cstring>
#include <sstream>
using namespace std;

int p;
string cur,input,tmp;
vector<string> path;
vector<string> vec_cur;

void deal_cur()
{
	tmp = cur;
	for(size_t i=0; i<cur.size(); ++i)
		if(tmp[i] == '/') tmp[i] = ' ';
	stringstream ss(tmp);
	while(ss>>tmp)
		vec_cur.push_back(tmp);
}

void deal_input()
{
	path.clear();
	size_t p;
	while((p=input.find("//")) != string::npos)
		input.erase(p,2);

	while((p=input.find("/./")) != string::npos)
		input.replace(p,3,"/");

	if(input[0] != '/') path = vec_cur;

	for(size_t i=0; i<input.size(); ++i)
		if(input[i] == '/') input[i] = ' ';
	stringstream ss(input);
	while(ss>>tmp)
	{
		//cout<<"tmp:"<<tmp<<"\n";
		if(tmp == "..")
		{
			if(!path.empty()) path.pop_back();
		}
		else path.push_back(tmp);
	}
}

void print()
{
	if(!path.empty())
	{
		for(int i=0; i<path.size(); ++i)
			cout<<"/"<<path[i];
	}
	else cout<<"/";
	cout<<"\n";
}

int main()
{
	cin>>p;
	cin.get();
	getline(cin,cur);
	deal_cur();
	while(p--)
	{
		getline(cin,input);
		deal_input();
		print();
	}
	
	return 0;
}

 

### CCF 2014年6月第3题:路径解析解决方案 对于给定的文件系统操作记录,目标是从这些记录中计算出当前目录下各文件和子目录的状态。此问题可以通过维护一个栈来模拟命令行中的目录切换过程。 #### 数据结构设计 为了高效处理输入指令并更新状态,可以采用如下方法: - 使用 `stack` 存储当前所在路径- 利用字典 `dict()` 或哈希表存储每个节点的信息(包括名称、类型以及大小),其中键为完整路径字符串,值则是一个元组 `(type, size)` 表示该位置对应的实体及其尺寸;如果遇到的是文件夹,则其初始容量设为零[^1]。 #### 输入解析逻辑 针对每一条命令执行相应的动作: 当接收到 `"cd /"` 命令时,清空堆栈并将根目录压入作为起始点。 ```python if command.startswith(&#39;cd /&#39;): stack.clear() stack.append(&#39;/&#39;) ``` 面对相对路径形式下的进入子级请求 `"cd name"` ,只需简单地把新一层加入到现有路径序列里即可完成转换工作。 ```python elif command.startswith(&#39;cd &#39;): target = command.split()[1] if not target.startswith(&#39;/&#39;): current_path = &#39;/&#39;.join(stack) + &#39;/&#39; + target.lstrip(&#39;/&#39;) else: current_path = target.rstrip(&#39;/&#39;) or &#39;/&#39; while stack and not current_path.startswith(&#39;/&#39;.join(stack)): stack.pop() parts = current_path.strip(&#39;/&#39;).split(&#39;/&#39;) for part in parts: full_part = (&#39;/&#39; if not stack else &#39;/&#39;.join(stack)) + &#39;/&#39; + part if part != &#39;&#39; and (not stack or stack[-1] != full_part): stack.append(full_part) ``` 对于返回上层的操作 `"cd .."` , 只需弹出最顶端元素实现退回到上级父级的功能. ```python elif command == "cd ..": if len(stack)>1: stack.pop(-1) ``` 最后一种情况即创建新的文件或文件夹 `"mkdir name"` 和 `"touch filename bytesize"` 。此时应先判断目的地址是否存在再决定是否新增项目。 ```python def add_entry(path, entry_type, size=0): entries[path] = (entry_type, size) for cmd in commands: ... elif cmd.startswith("mkdir"): dir_name = "/".join(stack)+"/"+cmd.replace("mkdir ", "") add_entry(dir_name,&#39;dir&#39;) elif cmd.startswith("touch"): file_info = cmd.replace("touch ","").rsplit(" ",1) file_name,size=file_info[0],int(file_info[1]) file_path="/".join(stack)+"/"+file_name add_entry(file_path,&#39;file&#39;,size) ``` 通过上述方式能够有效地追踪每一次变动后的最新布局状况,并最终输出所求的结果集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值