控制台下字典序蛇形打印目录树

本文介绍了一种实现ZIP归档文件中目录树状结构重建的方法。通过分析归档文件内的路径信息,利用C++编程语言中的map和set数据结构来构建目录树,并实现了递归输出目录树的功能。

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

在控制台下做到类似下图的效果:

这里写图片描述

具体题目背景:[点这儿].

题目:

在ZIP归档文件中,保留着所有压缩文件和目录的相对路径和名称。当使用WinZIP等GUI软件打开ZIP归档文件时,可以从这些信息中重建目录的树状结构。请编写程序实现目录的树状结构的重建工作。

输入格式:

输入首先给出正整数 N(104) ,表示ZIP归档文件中的文件和目录的数量。随后 N 行,每行有如下格式的文件或目录的相对路径和名称(每行不超过260个字符):

  • 路径和名称中的字符仅包括英文字母(区分大小写);
  • 符号“\”仅作为路径分隔符出现;
  • 目录以符号“\”结束;
  • 不存在重复的输入项目;
  • 整个输入大小不超过2MB。

输出格式:

假设所有的路径都相对于root目录。从root目录开始,在输出时每个目录首先输出自己的名字,然后以字典序输出所有子目录,然后以字典序输出所有文件。注意,在输出时,应根据目录的相对关系使用空格进行缩进,每级目录或文件比上一级多缩进2个空格。

输入样例:

7
b
c\
ab\cd
a\bc
ab\d
a\d\a
a\d\z\

输出样例:

root
  a
    d
      z
      a
    bc
  ab
    cd
    d
  c
  b

解析:

由于给出的是一系列的字符串路径,因此我们就要先建立这颗目录树;

这里就要根据题目要求合理选择相应的数据结构了,由于需要字典序,所以我使用了setmap作为其元素的集合和其子目录的集合,这样查找的效率与字典序就都可以满足了;

注意一点,存储目录时,存储的是其指针,这样可以有效节省内存空间,所以在程序结束时要记得手动释放,不然会造成内存泄露;

建好目录树后就是递归输出就好了.

代码:

#include <bits/stdc++.h>

using namespace std;

typedef struct tagDir Dir;
typedef Dir *pDir;

struct tagDir {
    map<string, pDir> childDir;
    set<string> childEle;
    tagDir(map<string, pDir> childDir = map<string, pDir>(), set<string> childEle = set<string>())
        : childDir(childDir), childEle(childEle) {}
};

void build(pDir root, string str)
{
    bool isEle = (str[str.size() - 1] != '\\');
    if (isEle)
        str.append("\\");
    vector<string> arrDir;
    for (string::size_type start = 0, end = str.find("\\", start); end != string::npos; start = end + 1, end = str.find("\\", start))
        arrDir.push_back(str.substr(start, end - start));
    for (size_t i = 0; i < arrDir.size() + (isEle ?  -1 : 0); root = root->childDir[arrDir[i++]])
        if (root->childDir.find(arrDir[i]) == root->childDir.end())
            root->childDir[arrDir[i]] = new Dir();
    if (isEle)
        root->childEle.insert(arrDir[arrDir.size() - 1]);
}

void outputSpace(int x)
{
    for (; x-- ; cout << " ");
}

void print(pDir root, int dep)
{
    for (auto ele : root->childDir) {
        outputSpace(dep * 2);
        cout << ele.first << endl;
        print(ele.second, dep + 1);
    }
    for (auto ele : root->childEle) {
        outputSpace(dep * 2);
        cout << ele << endl;
    }
}

void freeMemory(pDir root)
{
    for (auto ele : root->childDir)
        freeMemory(ele.second);
    root->childDir.clear();
    root->childEle.clear();
    delete root;
}

int main()
{
    int n;
    while (cin >> n) {
        pDir root = new Dir();
        string str;
        for (int i = 0; i < n; i++) {
            cin >> str;
            build(root, str);
        }

        cout << "root" << endl;
        print(root, 1);

        freeMemory(root);
    }
    return 0;
}

后台数据:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值