PAT DS 4-09. 笛卡尔树

来源:互联网 发布:红外触摸算法 编辑:程序博客网 时间:2024/05/16 04:53

简单的问题不必复杂话,应该直接码出来再说。

这题在printDirTree时打算用栈来保存每层目录,因为想着直接比较可能会比较费时。结果绕了一圈,发现还是直接比较简单明了。

这题我的思路是,先qsort所有路径,再输出目录树。

qsort的比较函数要仔细思考,避免遗漏边界(比如ab\cd\ 和ab\cd 的比较,ab\cd 和ab\c 的比较)。

输出目录树主要是前后两条路径的比较,要记录目录层数和相同路径的截止点。


<span style="font-size:18px;">#include <stdio.h>#include <assert.h>#include <stdbool.h>#define NAME_SIZE 261int n;char input[10000][NAME_SIZE];int nameCmp(const void *v1, const void *v2);void printDirTree();int main(void){#ifdef DEBUGfreopen("in.txt", "r", stdin);#endifscanf("%d", &n);int i=0;for(; i<n; ++i)scanf("%s", *(input+i));#ifdef DEBUGprintf("\nOriginal data:\n");for(i=0; i<n; ++i)printf("%s\n", *(input+i));#endifqsort(input, n, NAME_SIZE, nameCmp);#ifdef DEBUGprintf("\nqsorted data:\n");for(i=0; i<n; ++i)printf("%s\n", *(input+i));#endifprintDirTree();return 0;}int nameCmp(const void *v1, const void *v2){#ifdef DEBUG//printf("in function nameCmp.\n");#endifchar *s1 = (char*)v1, *s2 = (char*)v2;int i=0;for(; s1[i]!=0 && s2[i]!=0; ++i){if(s1[i] == s2[i])continue;else if(s1[i] == '\\')return -1;else if(s2[i] == '\\')return 1;elsebreak;}assert(s1[i] != s2[i]);if(s1[i] == 0 && s1[i-1] == '\\')return -1;if(s2[i] == 0 && s2[i-1] == '\\')return 1;int j=i;if(s1[j] < s2[j]){for(j=i; s1[j]!=0; ++j)if(s1[j] == '\\')return -1;for(j=i; s2[j]!=0; ++j)// only if there's no directory in s1if(s2[j] == '\\')// but is at least one directory in s2return 1;// will return 1return -1;}if(s1[j] > s2[j]){for(j=i; s2[j]!=0; ++j)if(s2[j] == '\\')return 1;for(j=i; s1[j]!=0; ++j)if(s1[j] == '\\')return -1;return 1;}}void printOne(char *file, int depth, int dMark);void printDirTree(){#ifdef DEBUGprintf("\nOutput:\n");#endifprintf("root\n");printOne(input[0], 1, 0);int i = 1;for(; i<n; ++i){// compare to the previous one and printint depth=1, dMark=-1;int j=0;for(; input[i][j]!=0 && input[i-1][j]!=0; ++j){if(input[i][j] == '\\'){++depth;dMark = j;}if(input[i][j] != input[i-1][j])break;}#ifdef DEBUG//printf("%s : %s\n", input[i-1], input[i]);#endifassert(input[i][j] != 0 || (input[i][j]==0 && input[i-1][j]=='\\'));printOne(input[i], depth, dMark+1);}}void printOne(char *file, int depth, int dMark){assert(file[0] != '\\' && depth > 0 && dMark >= 0);char tmp[261];int i=dMark, k=0;for(; file[i] != 0; ++i, ++k){if(file[i] == '\\'){tmp[k] = 0;for(k=0; k<depth; ++k)printf("  ");printf("%s\n", tmp);++depth;k=-1;continue;}tmp[k] = file[i];}if(k > 0){tmp[k] = 0;for(k=0; k<depth; ++k)printf("  ");printf("%s\n", tmp);}}</span>


0 0