在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
作者: DS课程组
单位: 浙江大学
时间限制: 400ms
内存限制: 64MB
代码长度限制: 16KB
解析 : 递归建树, 分割字符串。
#include <bits/stdc++.h>
const int MAXSIZE = 10010;
using namespace std;
typedef struct Directory
{
char key[270];
int DirectoryNum;
int FileNum;
struct Directory * DirectoryChild[MAXSIZE];
struct File * FileChild[MAXSIZE];
}Directory;
typedef struct File
{
char key[270];
}File;
typedef Directory *DirectoryPtr;
typedef Directory *Tree;
typedef File *FilePtr;
int N;
bool cmp1(FilePtr p1, FilePtr p2)
{
return strcmp(p1->key, p2->key) < 0;
}
bool cmp2(DirectoryPtr p1, DirectoryPtr p2)
{
return strcmp(p1->key, p2->key) < 0;
}
bool Insert(Tree &t, char s[270])
{
int len = strlen(s);
if(len == 0)
{
return false;
}
else
{
char key[270], temp[270];
int IsFile = 1;
for(int i = 0; i < len; ++i)
{
if(s[i] == '\\')
{
IsFile = 0;
strncpy(key, s, i);
strncpy(temp,s + i + 1, len - i - 1);
temp[len - i - 1] = '\0';
key[i] = '\0';
// printf("==%s+%s\n", key, temp);
break;
}
}
if(IsFile == 1)
{
FilePtr fp = (FilePtr)malloc(sizeof(File));
strcpy(fp->key, s);
t->FileChild[t->FileNum++] = fp;
// sort(t->FileChild, t->FileChild + t->FileNum, cmp1);
return true;
}
else
{
DirectoryPtr dp;
int IsFind = 0;
for(int j = 0; j < t->DirectoryNum; ++j)
if(strcmp(t->DirectoryChild[j]->key, key) == 0)
{
IsFind = 1;
dp = t->DirectoryChild[j];
break;
}
if(IsFind != 1)
{
dp = (DirectoryPtr)malloc(sizeof(Directory));
strcpy(dp->key, key);
dp->DirectoryNum = dp->FileNum = 0;
t->DirectoryChild[t->DirectoryNum++] = dp;
// sort(t->DirectoryChild, t->DirectoryChild + t->DirectoryNum, cmp2);
}
Insert(dp, temp);
}
}
}
Tree BuildTree()
{
char s[270];
Tree T;
T = (Tree)malloc(sizeof(Directory));
strcpy(T->key, "root");
T->DirectoryNum = T->FileNum = 0;
scanf("%d", &N);
for(int i = 1; i <= N; ++i)
{
scanf("%s", s);
Insert(T, s);
}
return T;
}
void Print(Tree t, int top)
{
for(int j = 0; j < top; ++j)
printf(" ");
printf("%s\n", t->key);
sort(t->DirectoryChild, t->DirectoryChild + t->DirectoryNum, cmp2);
for(int i = 0; i < t->DirectoryNum; ++i)
{
Print(t->DirectoryChild[i], top + 1);
}
sort(t->FileChild, t->FileChild + t->FileNum, cmp1);
for(int i = 0; i < t->FileNum; ++i)
{
for(int j = 0; j < top + 1; ++j)
printf(" ");
printf("%s\n", t->FileChild[i]->key);
}
}
int main()
{
Tree T;
T = BuildTree();
Print(T, 0);
}