在控制台下做到类似下图的效果:
具体题目背景:[点这儿].
题目:
在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
解析:
由于给出的是一系列的字符串路径,因此我们就要先建立这颗目录树;
这里就要根据题目要求合理选择相应的数据结构了,由于需要字典序,所以我使用了
set
和map
作为其元素的集合和其子目录的集合,这样查找的效率与字典序就都可以满足了;注意一点,存储目录时,存储的是其指针,这样可以有效节省内存空间,所以在程序结束时要记得手动释放,不然会造成内存泄露;
建好目录树后就是递归输出就好了.
代码:
#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;
}