如有不对,不吝赐教
进入正题:
在ZIP归档文件中,保留着所有压缩文件和目录的相对路径和名称。当使用WinZIP等GUI软件打开ZIP归档文件时,可以从这些信息中重建目录的树状结构。请编写程序实现目录的树状结构的重建工作。
输入格式:
输入首先给出正整数N(≤10^4),表示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<stdio.h>
#include<malloc.h>
#include<string.h>
struct File{
int space; //到这个文件需要打印的空格数目
char name[261];
struct File *sibFile; //同级文件链表
};
struct Catalog{
int space; //到该目录需要打印的空格数目
char name[261];
struct Catalog *sonCat; //子目录分支
struct Catalog *sibCat; //同级目录分支 按字典序排序
struct File *file; //文件分支
};
struct Catalog *Add(struct Catalog *root,char *input);
struct Catalog *AddCat(struct Catalog *root,char *name,char *input);
struct Catalog *AddFile(struct Catalog *root,char *name);
void Print(struct Catalog *root);
int main(void)
{
int N,i;
struct Catalog *root; //目录树的根
char input[261]; //每行最多260个字符
char temp[5]="root";
scanf("%d",&N);
root=(struct Catalog *)malloc(sizeof(struct Catalog));
root->file=(struct File *)malloc(sizeof(struct File));
root->sibCat=(struct Catalog *)malloc(sizeof(struct Catalog));
root->file=NULL;
root->sibCat=NULL;
root->sonCat=NULL;
strcpy(root->name,temp);
root->space=0; //初始化根节点
for(i=0;i<N;i++){
scanf("%s",input);
root=Add(root,input);
}
Print(root);
return 0;
}
struct Catalog *Add(struct Catalog *root,char *input)
{
int i,j;
char name[261]; //提取出的姓名
for(i=0,j=0;'\\'!=input[i]&&input[i];i++) //看有没有问题
name[j++]=input[i];
name[j]='\0';
if('\\'==input[i]) //表示是目录
root=AddCat(root,name,input+i+1); //略过'\\'
else
root=AddFile(root,name);
return root;
}
struct Catalog *AddCat(struct Catalog *root,char *name,char *input)
{
struct Catalog *cur=root->sonCat;
struct Catalog *newOne;
newOne=(struct Catalog *)malloc(sizeof(struct Catalog));
newOne->sibCat=(struct Catalog *)malloc(sizeof(struct Catalog));
newOne->sonCat=(struct Catalog *)malloc(sizeof(struct Catalog));
newOne->file=(struct File *)malloc(sizeof(struct File));
newOne->sibCat=NULL;
newOne->sonCat=NULL;
newOne->space=root->space+2;
newOne->file=NULL;
strcpy(newOne->name,name); //初始化新节点
do{
if(!cur){
root->sonCat=newOne;
break;
} //子目录树为空树
if(strcmp(cur->name,name)>0){
newOne->sibCat=cur;
root->sonCat=newOne;
break;
} //比第一个目录的字典序小
if(!strcmp(cur->name,name)){
cur=Add(cur,input);
free(newOne);
return root;
} //输入的就是目录树的第一个目录
while(cur->sibCat&&strcmp(cur->sibCat->name,name)<0)
cur=cur->sibCat; //找到插入的位置
if(cur->sibCat){
if(!strcmp(cur->sibCat->name,name)){
cur->sibCat=Add(cur->sibCat,input);
return root;
} //和其字典序相等
else{
newOne->sibCat=cur->sibCat;
cur->sibCat=newOne;
}
} //插入位置在树的中间
else
cur->sibCat=newOne;
}while(0);
if(input[0]) //还有子目录或者文件的话
newOne=Add(newOne,input);
return root;
}
struct Catalog *AddFile(struct Catalog *root,char *name)
{
if(!name) //没有添加的文件分支
return root;
struct File *cur=root->file;
struct File *newOne;
newOne=(struct File *)malloc(sizeof(struct File));
newOne->sibFile=(struct File *)malloc(sizeof(struct File));
strcpy(newOne->name,name);
newOne->sibFile=NULL;
newOne->space=root->space+2; //初始化新节点
if(!cur){
root->file=newOne;
return root;
} //文件树为空
if(strcmp(cur->name,name)>0){
newOne->sibFile=cur;
root->file=newOne;
return root;
} //输入的文件比第一个文件名字典序更小
while(cur->sibFile&&strcmp(cur->sibFile->name,name)<0)
cur=cur->sibFile;
//找到插入位置
if(!cur->sibFile)
cur->sibFile=newOne;
else{
newOne->sibFile=cur->sibFile;
cur->sibFile=newOne;
}
return root;
}
void Print(struct Catalog *root)
{
if(!root)
return ;
short i;
struct Catalog *curCat=root->sonCat;
struct File *curFile=root->file;
for(i=0;i<root->space;i++)
putchar(' ');
printf("%s\n",root->name); //输出当前根目录名称
while(curCat){
Print(root->sonCat);
root->sonCat=curCat->sibCat;
free(curCat);
curCat=NULL;
curCat=root->sonCat;
}
while(curFile){
for(i=0;i<curFile->space;i++)
putchar(' ');
printf("%s\n",curFile->name);
root->file=curFile->sibFile;
free(curFile);
curFile=NULL;
curFile=root->file;
} //打印文档名字
return ;
}
测试结果: