CCF 201604-3 路径解析

本文介绍了CCF201604-3路径解析问题的解决方法,通过将相对路径添加到当前目录并进行规范化处理,利用栈操作去除冗余部分。使用getline读取输入并借助stringstream处理字符串。

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

CCF 201604-3 路径解析 传送门

没看懂题目, 感觉乱七八糟的, 这是什么规则, 怎么看不懂啊? 无奈之下搜了搜题解, 自己按照大佬的方法做了一次, 觉得好像真是那么回事. 大概是因为没有路径查询的相关经验吧, 所以看题的时候会无法理解一些反常识的操作. 会觉得莫名其妙.

总之, 方法就是如果查询的路径是相对路径, 那么把它添加到当前目录里面去, 绝对路径不变.

然后对新的路径进行正规化处理, 以有一个或多个/作为分隔符, 遇到.就直接跳过去, 这里不太好理解, 这样的话这个.有什么用? 遇到..就把最后一个元素删除, 嗯, 就是类似栈的操作. 其余的都加入到栈中.

要注意的是可能会读取空字符查询, 而普通的cin是会忽略的, 所以用getline来读取一行. 代码中非常巧妙地用了stringstream来处理, 十分值得借鉴学习.

代码只有三十多行, 理解了题目意思就很简单了, 如果理解不了(比如我), 就会一头雾水. 话说这是我的锅还是CCF的锅?

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

int main()
{
    int n;
    cin >> n;
    string path, s, str;
    cin >> path;
    cin.get();  // 用getline时千万要注意吸收这个换行符
    for (int i = 0; i < n; ++i) {
        getline(cin, str);
        if (str == "") str = path;
        if (str[0] != '/') str = path + '/' + str;
        for (int j = 0; j < str.size(); ++j) {
            if (str[j] == '/') str[j] = ' ';
        }
        vector<string> sta;
        stringstream ss(str);
        while (ss >> s) {
            if (s == ".") continue;
            else if (s == ".." && !sta.empty()) sta.pop_back();
            else if (s != "..") sta.push_back(s);
        }
        cout << '/';
        for (int j = 0; j < sta.size(); ++j) {
            if (j) cout << '/';
            cout << sta[j];
        }
        cout << endl;
    }
}

对了, 用getline注意吸收前面的换行符.

### 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) ``` 通过上述方式能够有效地追踪每一次变动后的最新布局状况,并最终输出所求的结果集。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值