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

来源:互联网 发布:网络直播在线观看 编辑:程序博客网 时间:2024/06/07 04:59

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

这里写图片描述

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

题目:

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

输入格式:

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

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

输出格式:

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

输入样例:

7bc\ab\cda\bcab\da\d\aa\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;}

后台数据:

这里写图片描述