PTA 7-9 目录树

来源:互联网 发布:搜狗输入法mac旧版本 编辑:程序博客网 时间:2024/06/18 09:10

7-9 目录树(30 分)

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

输入格式:

输入首先给出正整数N(104),表示ZIP归档文件中的文件和目录的数量。随后N行,每行有如下格式的文件或目录的相对路径和名称(每行不超过260个字符):

  • 路径和名称中的字符仅包括英文字母(区分大小写);
  • 符号“\”仅作为路径分隔符出现;
  • 目录以符号“\”结束;
  • 不存在重复的输入项目;
  • 整个输入大小不超过2MB。

输出格式:

假设所有的路径都相对于root目录。从root目录开始,在输出时每个目录首先输出自己的名字,然后以字典序输出所有子目录,然后以字典序输出所有文件。注意,在输出时,应根据目录的相对关系使用空格进行缩进,每级目录或文件比上一级多缩进2个空格。

输入样例:

7bc\ab\cda\bcab\da\d\aa\d\z\

输出样例:

root  a    d      z      a    bc  ab    cd    d  c  b
作者: DS课程组
单位: 浙江大学
时间限制: 400ms
内存限制: 64MB

思考过程:

一看就是建树题。为了方便处理,分为两种节点,目录(Tree)和文件(File)。文件只储存一个name,目录则储存有:name,子目录数组(child),子文件目录(files),和两个数组的元素数目(child_num 和 files_num)。 递归建树时传入字符串和父目录(parent)。

然后进行递归建树,依据传入字符串不同大致有三种情况:\后还有字符,则取第一个\前的字符串为name,查找一下父目录的child里面是否已有,无则创个加进去,修改字符串和parent后在递归(修改字符串直接用地址指针操作);\后无字符,操作基本和前者相同,但不用在进行递归;查找不到\,说明这是个File,直接创个新的File加进去就ok。

输出自然也是递归,注意把files放在chiid后面输出,别忘了排字典序。

题外话:

对树一直略有恐惧,好歹这次分两次,一次大概两个小时,终于弄出来了,果然贼爽。其中还重写了一次,果然搞得晕了还是重写比较好,瞎改没有未来。遇到个奇怪的问题,本来是用qsort来排序的 ,以为会快些,但排出来总是个错的,“ab”总在“a”的前面,换用sort,比较语句也没有变,结果就对了。之前用qsort也出现过其它的奇怪现象,实在搞不懂。   一开始name还有数组开的都比较小,怕超时,没想到题目还有个最长name测试例,没想到加大依然过,我好像总是低估了电脑的内存和运算能力。

代码:

#include using namespace std;typedef struct File_ *File;typedef struct File_{    char name[270];};typedef struct Node *Tree;typedef struct Node{    char name[270];    Tree child[507];    File files[507];    int child_num = 0;    int files_num = 0;};bool cmp1(Tree a, Tree b){    return strcmp(a -> name, b -> name) < 0;}bool cmp2(File a, File b){    return strcmp(a -> name, b -> name) < 0;}void solve(char *s, Tree parent){    int finds = 0, pos = 0,len = strlen(s);    for(; (s[pos] != 92) && pos < len; ++pos)        ;    if(s[pos] == 92)    {            char name_[270];            int exist = 0;            strncpy(name_,s,pos);            name_[pos] = '\0';            Tree now ;            for(int i = 0; i < parent -> child_num; ++i)            {                if(strcmp(name_, parent -> child[i] -> name) == 0)                {                    exist = 1;                    now = parent -> child[i];                    break;                }            }            if(!exist)            {                now = (Tree)malloc(sizeof(Node));                strcpy(now -> name, name_);                now -> child_num = 0;                now -> files_num = 0;                parent -> child[parent ->child_num] = now;                parent ->child_num++;            }            if(pos <(strlen(s)-1))            {                solve(s + pos +1, now);            }            else            return ;    }    else    {        File newone = (File)malloc(sizeof(File_));        strcpy(newone -> name,s);        parent -> files[parent -> files_num] = newone;        parent -> files_num++;        return ;    }}void PrintTree(Tree now, int depth){    for(int i = 0; i < depth; ++i)        printf("  ");    printf("%s\n",now -> name);    depth++;    sort(now -> child, now -> child + now -> child_num, cmp1);    for(int i = 0; i < now -> child_num; ++i)        PrintTree(now -> child[i], depth);    sort(now -> files, now -> files + now -> files_num, cmp2);    for(int i = 0; i < now -> files_num; ++i)    {        for(int i1 = 0; i1 < (depth); ++i1)        {            printf("  ");        }        printf("%s\n",now -> files[i] -> name);    }    return ;}int main(){    int n;    scanf("%d", &n);    Tree root = (Tree)malloc(sizeof(Node));    strcpy(root -> name, "root");    while(n--)    {        char str[270];        scanf("%s",str);        solve(str, root);    }    PrintTree(root,0);    return 0;}#includeusing namespace std;const int MAXN = 2e6 +10;const int inf = 1e5 + 10;struct Node{    char id[20];    int length;    int next ;    Node()    {        length = 0;    }}paser[MAXN];int n,m,k;int start = 0,head[MAXN];int Hash (char *s){    long long ans = 0;    for(int i = 0; i <17; ++i)    {        ans = ans*10 + s[i] - '0';    }    if(s[17] == 'x') ans += 1e18;    else ans = ans * 10 + s[17] - '0';    return ans%inf;}void Insert (){    char str[20];    int num;    scanf("%s%d",str, &num);    int pos = Hash(str);    int ok = 0;    num = max(num,m);    for(int i = head[pos]; i != -1; i = paser[i].next)    {        if(strcmp(paser[i].id, str)==0)        {            paser[i].length += num;            ok = 1;        }    }    if(!ok)    {        strcpy(paser[start].id,str);        paser[start].length = num;        paser[start].next = head[pos];        head[pos] = start++;    }}void PrintAns(){    char str[20];    scanf("%s",str);    int num = Hash(str),ok = 0;    for(int i = head[num]; i != -1; i = paser[i].next)    {        if( strcmp(paser[i].id,str)==0)        {            printf("%d\n",paser[i].length);            return ;        }    }    puts("No Info");    return ;}int main(){    scanf("%d%d",&n,&m);    memset(head,-1,sizeof(head));    for(int i = 0 ; i < n; ++i)        Insert();    scanf("%d", &k);    while(k--)    {        PrintAns();    }}

原创粉丝点击