#训练4# 2-目录树

这篇博客介绍了一种使用C++构建和遍历文件系统树的方法。通过建立一个特殊的树结构,程序能够区分文件和目录,并进行深度优先搜索。文章强调了正确处理文件路径和大小写敏感性的重要性,并提供了代码示例。作者分享了在解决样例时遇到的错误,即忽视了大小写敏感性导致的失败,以及对stringstream方法的思考。

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

题目

https://pintia.cn/problem-sets/15/problems/857
在这里插入图片描述

思路

建树,不是二叉树,应该叫父母兄弟树还是啥来着。。
然后搜索得到结果
记得标记一下是文件(记0)还是目录(记1)
在这里插入图片描述
在这里插入图片描述

代码

#include <iostream>
#include <cstring>
#include <stack>
#include <algorithm>
#include <queue>
#include <map>
#include <string>

#define MAXX 1010
using namespace std;

struct node
{
    string name;
    int f;
    vector<node> v;

    node()
    {}   //初始化,报错
    node(string name, int f) : name(name), f(f)
    {}

    bool operator<(const node n2) const
    {
        if (f == n2.f) return name < n2.name;
        return f > n2.f;
    }
} root;


string fname[MAXX];
int ftype[MAXX];

void add(node &no, int depth, int cnt)
{
    if (cnt == depth)
        return;
    int i;
    for (i = 0; i < no.v.size(); ++i)
    {
        if (no.v[i].name == fname[depth] && no.v[i].f == ftype[depth])
        {
            add(no.v[i], depth + 1, cnt);
            return;
        }
    }
    no.v.push_back(node{fname[depth], ftype[depth]});
    add(no.v[i], depth + 1, cnt);
}

void dfs(node no, int t)
{
    for (int i = 0; i < t; ++i)
    {
        cout << "  ";
    }
    cout << no.name << endl;
    for (int i = 0; i < no.v.size(); ++i)
    {
        sort(no.v.begin(), no.v.end());
        dfs(no.v[i], t + 1);
    }
}

int main()
{
    int n;
    cin >> n;
    //根初始化
    root.name = "root";
    root.f = 0;
    root.v.clear();
    getchar();
    //建造子树
    while (n--)
    {
        string s;
        getline(cin, s);
        string tmp;
        int cnt = 0;
        //  cout << s << endl;
        int len = s.length();
        for (int i = 0; i <= len - 1; ++i)
        {
            if (isalpha(s[i]))  //区分大小写!!!
                tmp += s[i];
            else
            {
                fname[cnt] = tmp;
                ftype[cnt] = 1;  //目录
                cnt++;
                tmp.clear();
            }
        }
        if (s[len - 1] != '\\')  //判断最后一位
        {
            fname[cnt] = tmp;
            ftype[cnt] = 0;  //文件
            cnt++;
            tmp.clear();
        }
//        for (int i = 0; i < cnt; ++i)
//        {
//            cout << fname[i] << ' ' << ftype[i] << endl;
//        }
        add(root, 0, cnt);
    }
    dfs(root, 0);
    return 0;
}

总结

  1. 最后一个样例怎么也过不了,本来想放弃了的,结果再看一遍题,是区分大小写的啊,〒▽〒我直接哭晕,自己一开始就看到了,但是当时偷懒没写全,结果就是这里过不去,啊啊啊啊啊啊啊啊啊难过
    List item
  2. 因为string s的结尾分两种情况,所以最后单独讨论一下就xin,一开始想得有些麻烦了。。还有一种思路可以参考一下,用stringstream做的,感觉很方便,但是这个娃虽说是过了题,但应该是写错了的,还应该考虑目录和文件重名的情况
		getline(cin, s);
        int f_ = 0; if(s[s.size()-1] == '\\') f_ = 1;   // 最后的目录标志
 
        for(int j = 0; j < s.size(); ++j)
            if(!isalpha(s[j])) s[j] = ' ';
        stringstream ss(s);
        cur = 0;
        while(ss >> t) {
            a[cur] = t;
            b[cur++] = 1;
        }
        if(!f_) b[cur-1] = 0;
  1. 建树和深搜还是要多熟悉一下!
  2. 觉得这个样例比较好
15
b
c\
ab\cd
a\bc
ab\d
a\d\a
a\d\z\
b\
c
ab\cd\e
a\bc\f
ab\d\g
a\d\a\h
a\d\z
sss

输出结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值