PTA 7-30 目录树 (30 point(s))

在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

结尾无空行

 

#include<bits/stdc++.h>
using namespace std;

struct Package{
    string name;
    vector<Package*> catalog;                   // 目录
    set<string> file;                           // 文件
};

void insert(Package* pack, string str){         // 把str字段插入pack目录下
    if(str.empty())                             // 字符串空退出函数
        return;
    int index = str.find('\\');                 // 返回第一个'\'出现的下标,若找不到返回-1
    if(index == -1)                             // 返回-1说明是文件
        pack->file.insert(str);
    else{
        Package* subPack = new Package();
        subPack->name = str.substr(0, index);   // 截取第一个'\'前内容 当前路径名称
        bool existed = false;
        for(auto p : pack->catalog)
            if(subPack->name == p->name){       // 若之前出现过该目录
                delete(subPack), subPack = p;   // 改变指针指向
                existed = true;
                break;
            }
        if(existed == false){                   // 未出现过加入文件夹列表
            pack->catalog.push_back(subPack);
        }
        insert(subPack, str.substr(index + 1)); // 取'\'后的字段 插入子文件夹
    }
}

void dfsSort(Package* pack){                    // 对当前目录下的文件夹按字典序排序
    sort(pack->catalog.begin(), pack->catalog.end(), 
         [](Package* a, Package* b){            // 传入的参数是指针* 所以需要以指针的方式获取成员变量
             return a->name < b->name;});
    for(auto p : pack->catalog)                 // 遍历子目录排序
        dfsSort(p);
}

void print(Package pack, int space){
    for(int i = 0; i < space; i++)              // 根据相对关系缩减空格
        cout << "  ";
    cout << pack.name << endl;                  // 当前目录名称
    for(auto log : pack.catalog)                // 先遍历子目录
        print(*log, space + 1);                 // 传入*auto地址 == Package结构体类型 相对关系+1
    for(auto f : pack.file){                    // 遍历子目录后文件
        for(int i = 0; i < space + 1; i++)      // 根据当前目录缩进子文件并输出
            cout << "  ";
        cout << f << endl;
    }
}

int main() {
    int n;
    cin >> n;
    Package* pack = new Package();
    pack->name = "root";
    while(n--){
        string str;
        cin >> str;
        insert(pack, str);                      // 传递对象地址以修改
    }
    dfsSort(pack);                              // 传递引用 修改顺序
    print(*pack, 0);                            // 仅输出 拷贝变量 不需要引用
}
// 试试C++的面向对象
#include<bits/stdc++.h>
using namespace std;

class Package{
    public:
        string name;
        vector<Package*> catalog;
        set<string> file;
    
        Package(){
        }
    
        Package(string s){
            name = s;
        }
};

void insert(Package* pack, string str){
    if(str.empty())
        return;
    int index = str.find('\\');
    if(index == -1)
        pack->file.insert(str);
    else{
        Package* subPack = new Package(str.substr(0, index));
        bool existed = false;
        for(auto p : pack->catalog)
            if(subPack->name == p->name){
                delete(subPack), subPack = p;
                existed = true;
                break;
            }
        if(existed == false){
            pack->catalog.push_back(subPack);
        }
        insert(subPack, str.substr(index + 1));
    }
}

void dfsSort(Package* pack){
    sort(pack->catalog.begin(), pack->catalog.end(), 
         [](Package* a, Package* b){
             return a->name < b->name;});
    for(auto p : pack->catalog)
        dfsSort(p);
}

void print(Package pack, int space){
    for(int i = 0; i < space; i++)
        cout << "  ";
    cout << pack.name << endl;
    for(auto log : pack.catalog)
        print(*log, space + 1);
    for(auto f : pack.file){
        for(int i = 0; i < space + 1; i++)
            cout << "  ";
        cout << f << endl;
    }
}

int main() {
    int n;
    cin >> n;
    Package* pack = new Package();
    pack->name = "root";
    while(n--){
        string str;
        cin >> str;
        insert(pack, str);
    }
    dfsSort(pack);
    print(*pack, 0);
}

参考代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值