pta 9 目录树 (30分) (树的遍历)

时间:2020-12-31 12:35:18


在ZIP归档文件中,保留着所有压缩文件和目录的相对路径和名称。当使用WinZIP等GUI软件打开ZIP归档文件时,可以从这些信息中重建目录的树状结构。请编写程序实现目录的树状结构的重建工作。

输入格式:

输入首先给出正整数N(\le 10^4104),表示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;
const int maxn=1e4;
char a[333];
struct p
{
    char str[333];
    int siz;
    int od;
    p*next[333];
};
int top;
bool cmp(p *a , p *b)
{
    if(a->od!=b->od)return a->od>b->od;
    else return strcmp(a->str,b->str)<0;
}
void pre(p*root)
{
    int i, j;
    for(i=0; i<top; i++)printf("  ");
    printf("%s\n", root->str);
    top++;
    char t[333];
    for(i=0; i<root->siz; i++)
    {
       sort(root->next, root->next+root->siz, cmp);
        pre(root->next[i]);

    }
    top--;
    return;
}
int main()
{

    int n;
    cin>>n;
    int i, j;
    p*root=(p*)malloc(sizeof(p));
    for(i=0; i<332; i++)root->next[i]=NULL;
    root->siz=0;
    strcpy(root->str, "root");
    int s=0, k;
    char e[333];
    p*q;
    top=0;
    for(i=0; i<n; i++)
    {
        q=root;
        scanf("%s", a);
        int siz;
        for(j=0; a[j]; j++)
        {
//            if(i==6)printf("%c", a[j]);
            if(a[j]=='\\')
            {
                e[s]='\0';
                siz=q->siz;
                for(k=0; k<q->siz; k++)
                {
                    if(strcmp(e, q->next[k]->str)==0)
                    {
                        q=q->next[k];
                        break;
                    }
                }
//                printf("%d %d\n", k, siz);
//                if(i==6)printf("%s %d %d\n", e, k, q);
                if(k>=siz)
                {
                    q->next[q->siz]=(p*)malloc(sizeof(p));
                    q->next[q->siz]->siz=0;
                    strcpy(q->next[q->siz]->str, e);
                    q->siz++;
                    q=q->next[siz];
                    q->od=1;
 //                   printf("%s",e);

                    s=0;
//                    printf("%s\n", e);

                }
                s=0;
            }
            else e[s++]=a[j];
        }
        if(!a[j] && a[j-1]!='\\')
        {
                    e[s]='\0';
                    siz=q->siz;
                    q->next[q->siz]=(p*)malloc(sizeof(p));
                    q->next[q->siz]->siz=0;
                    strcpy(q->next[q->siz]->str, e);
                    q->siz++;
                    q=q->next[siz];
                    q->od=0;
                    s=0;
//                    printf("%s\n", e);
        }
    }
//    cout<<123<<endl;
//    printf("root\n");
    pre(root);
    return 0;
}