简单的问题不必复杂话,应该直接码出来再说。
这题在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 261
int n;
char input[10000][NAME_SIZE];
int nameCmp(const void *v1, const void *v2);
void printDirTree();
int main(void)
{
#ifdef DEBUG
freopen("in.txt", "r", stdin);
#endif
scanf("%d", &n);
int i=0;
for(; i<n; ++i)
scanf("%s", *(input+i));
#ifdef DEBUG
printf("\nOriginal data:\n");
for(i=0; i<n; ++i)
printf("%s\n", *(input+i));
#endif
qsort(input, n, NAME_SIZE, nameCmp);
#ifdef DEBUG
printf("\nqsorted data:\n");
for(i=0; i<n; ++i)
printf("%s\n", *(input+i));
#endif
printDirTree();
return 0;
}
int nameCmp(const void *v1, const void *v2)
{
#ifdef DEBUG
//printf("in function nameCmp.\n");
#endif
char *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;
else
break;
}
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 s1
if(s2[j] == '\\') // but is at least one directory in s2
return 1; // will return 1
return -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 DEBUG
printf("\nOutput:\n");
#endif
printf("root\n");
printOne(input[0], 1, 0);
int i = 1;
for(; i<n; ++i){ // compare to the previous one and print
int 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]);
#endif
assert(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>