5-30 目录树 (30分)

5-30 目录树 (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

思路
注意区别文件和目录,这是两个东西。不存在的目录要随时创建。文件底下是不能挂有别的什么东西。
点击访问 PTA-测验

#include <stdio.h>
#include<stdlib.h>
#include <string.h>

typedef int Bool;
typedef struct node *Node;
struct node {
    char*Name;
    Bool isMulu;//先判断是不是目录,是目录才有file和mulu,否则只可能有brother
    Node File;//指示本目录的子目录
    Node Mulu;//指示本目录的子文件
    Node Brother;//指示和本目录或文件平行的目录或文件
} Head;
void Print(Node,int);
void Read();
Node New(char*);
Node InsertMulu(Node,char*);
Node InsertFile(Node,char*);
/* 评测结果 时间  结果  得分  题目  编译器     用时(ms)  内存(MB)  用户
2016-08-30 11:00    答案正确    30  5-30    gcc     17  2   569985011
测试点结果 测试点   结果  得分/满分   用时(ms)  内存(MB)
测试点1    答案正确    18/18   2   1
测试点2    答案正确    2/2     1   1
测试点3    答案正确    10/10   17  2
查看代码*/
int main() {
//  printf("%d",strlen("12"));
    int n;
    scanf("%d",&n);
    Head.Name=(char*)malloc(sizeof(char)*5);
    strcpy(Head.Name,"root");
    Head.File=NULL;
    Head.Mulu=NULL;
    Head.Brother=NULL;
    Head.isMulu=1;
    for(int i=0; i<n; i++) {
        getchar();
        Read();
//      printf("-%p-",Head);
//      Print(Head.Son,0);
    }
    Print(&Head,0);
    return 0;
}

void Read() {
    char FileName[261];
    Node temp=&Head;
    scanf("%s",FileName);
//  printf("[%s]",FileName);

    char words[261];
    int j,L=0;
    for(int i=0; i<strlen(FileName); i++) {
        if(FileName[i]=='\\') {
            for(j=L; j<i; j++) {
                words[j-L]=FileName[j];
            }
            words[j-L]='\0';
//          printf("(%s)",words);
            temp->Mulu=InsertMulu(temp->Mulu,words);
            temp=temp->Mulu;
            while(strcmp(temp->Name,words))temp=temp->Brother;
            L=i+1;
        }
    }
    if(L<strlen(FileName)) {
        for(j=L; j<=strlen(FileName); j++) {
            words[j-L]=FileName[j];
        }
//      printf("(%s)",words);
        temp->File=InsertFile(temp->File,words);
    }
}


Node InsertMulu(Node H,char*K) {

    if(!H||strcmp(H->Name,K)>0) {
        Node temp=New(K);
        temp->Brother=H;
        return temp;
    }
    if(strcmp(H->Name,K)==0)return H;
    H->Brother=InsertMulu(H->Brother,K);
    return H;
}
Node InsertFile(Node H,char*K) {
    if(!H||strcmp(H->Name,K)>0) {
        Node temp=New(K);
        temp->isMulu=0;
        temp->Brother=H;
        return temp;
    }
    H->Brother=InsertFile(H->Brother,K);
    return H;
}
Node New(char*K) {
    Node temp=(Node)malloc(sizeof(struct node));
    temp->Name=(char*)malloc(sizeof(char)*(strlen(K)+1));
    strcpy(temp->Name,K);
    temp->Brother=NULL;
    temp->File=NULL;
    temp->Mulu=NULL;
    temp->isMulu=1;//默认是在建目录
    return temp;
}
void Print(Node H,int Space) {
    if(H) {
        for(int i=0; i<Space; i++)printf(" ");
        printf("%s\n",H->Name);
        if(H->isMulu==1)
            Print(H->Mulu,Space+2);
        Print(H->File,Space+2);
        Print(H->Brother,Space);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值