问题描述:
4-8 目录树(30 分)
在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<iostream>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<queue>
using namespace std;
struct Tree{
char name[265];
int num;
struct Tree *zm;
struct Tree *zw;
struct Tree *xw;
struct Tree *xm;
};
struct node{
char name[265];
int flag;
};
queue<node>q1;
queue<Tree*>q2;
char s[265],ss[265];
int len[10005];
struct Tree *create(struct Tree *T)
{
struct node a;
struct Tree *Tt,*t,*q,*p;
Tt = T;
q2.push(Tt);
while(!q1.empty())
{
t = q2.front();
a = q1.front();
q1.pop();
q2.pop();
if(a.flag==1)
{
if(t->zm==NULL)
{
t->zm = (struct Tree*)malloc(sizeof(struct Tree));
strcpy(t->zm->name,a.name);
t->zm->num = t->num+2;
t->zm->xm=t->zm->xw=t->zm->zm=t->zm->zw=NULL;
q2.push(t->zm);
}
else
{
q = (struct Tree*)malloc(sizeof(struct Tree));
strcpy(q->name,a.name);
q->num = t->num+2;
q->xm=q->xw=q->zm=q->zw=NULL;
p = t->zm;
while(p)
{
if(strcmp(t->zm->name,q->name)>0)
{
q->xm = t->zm;
t->zm = q;
break;
}
else if(p->xm==NULL&&strcmp(p->name,q->name)<0)
{
p->xm = q;
break;
}
else if(strcmp(p->name,q->name)<0&&strcmp(p->xm->name,q->name)>0)
{
q->xm = p->xm;
p->xm = q;
break;
}
else if(strcmp(p->name,q->name)==0)
{
q = p;
break;
}
p = p->xm;
}
q2.push(q);
}
}
if(a.flag==2)
{
if(t->zw==NULL)
{
t->zw = (struct Tree*)malloc(sizeof(struct Tree));
strcpy(t->zw->name,a.name);
t->zw->num = t->num+2;
t->zw->xm=t->zw->xw=t->zw->zm=t->zw->zw=NULL;
q2.push(t->zw);
}
else
{
q = (struct Tree*)malloc(sizeof(struct Tree));
strcpy(q->name,a.name);
q->num = t->num+2;
q->xm=q->xw=q->zm=q->zw=NULL;
p = t->zw;
while(p)
{
if(strcmp(t->zw->name,q->name)>0)
{
q->xw = t->zw;
t->zw = q;
break;
}
else if(p->xw==NULL&&strcmp(p->name,q->name)<0)
{
p->xw = q;
break;
}
else if(strcmp(p->name,q->name)<0&&strcmp(p->xw->name,q->name)>0)
{
q->xw = p->xw;
p->xw = q;
break;
}
else if(strcmp(p->name,q->name)==0)
{
q = p;
break;
}
p = p->xw;
}
q2.push(q);
}
}
}
q2.pop();
return Tt;
}
void output(struct Tree *T)
{
for(int i = 0; i < T->num; i++)
{
printf(" ");
}
printf("%s\n",T->name);
if(T->zm) output(T->zm);
if(T->zw) output(T->zw);
if(T->xw) output(T->xw);
if(T->xm) output(T->xm);
}
int main()
{
struct Tree *T;
struct node ni;
T = (struct Tree*)malloc(sizeof(struct Tree));
char *p = "root";
strcpy(T->name,p);
T->num = 0;
T->xm=T->xw=T->zm=T->zw=NULL;
int n,i,j,k = 0;
scanf("%d",&n);
getchar();
for(i = 0; i < n; i++)
{
gets(s);
len[i] = strlen(s);
for(j = 0; j <= len[i]; j++)
{
if(s[j]!='\\'&&s[j]!='\0')
{
ss[k++] = s[j];
continue;
}
if(s[j]=='\\')
{
ni.flag = 1;
strcpy(ni.name,ss);
q1.push(ni);
if(j==len[i]-1)
{
T = create(T);
k = 0;
memset(ss,0,sizeof(ss));
break;
}
else
{
k = 0;
memset(ss,0,sizeof(ss));
continue;
}
}
else
{
ni.flag = 2;
strcpy(ni.name,ss);
q1.push(ni);
T = create(T);
}
k = 0;
memset(ss,0,sizeof(ss));
}
}
output(T);
}