在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);
}