[topic] フォルダパス一覧のツリー構造への変換

(相対)フォルダのパスの一覧が与えられ、そのフォルダパスの一覧をツリー構造に変換してください。
フォルダパスの区切り文字は'\'文字を使用しています。

以下のような1行1パスのフォルダのパスがあった場合、
 abc\def
 abc\def\gh
 abc\def\ij
 abc\jk\lm
 de

イメージとして、以下のようなツリー構造を構築できればOKです。
 ROOT
 ┗abc
  ┗def
   ┗gh
   ┗ij
  ┗jk
   ┗lm
 ┗de

ツリーですのでルートがあります。上記のフォルダ一覧はルート以下にぶら下げてください。また、同じフォルダにぶら下がっているサブフォルダの名前は重複させてはいけません。

上記のような出力は結果の分かりやすさとしてあった方がいいですが、なければないで構いません。また、ASやJavaFXでグラフィカルな結果を表示するプログラムでも構いませんが、データ構造はちゃんと作ってください。

Posted feedbacks - C

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Node {
    char *content;
    int content_size;
    struct Node **children;
    int children_size;
    int num_children;
};

struct Node *new_node( char *content );
struct Node *add_node_child( struct Node *node, char *content );
struct Node *search_node_child( struct Node *node, char *content );
void dump_node( struct Node *node );
void delete_node( struct Node *node );

int main() {
    int size = 32;
    char *dirname;
    int index = 0;
    int c;
    struct Node *tree;
    struct Node *t;
    tree = new_node( "ROOT" );
    dirname = malloc( size );
    if( tree == 0 || dirname == 0 ) {
        goto error;
    }
    t = tree;
    while( ( c = getchar() ) != -1 ) {
        struct Node *new_t;
        switch( c ) {
        case '\\':
        case '\n':
            dirname[index] = 0;
            index = 0;
            new_t = search_node_child( t, dirname );
            if( new_t == 0 ) {
                new_t = add_node_child( t, dirname );
            }
            if( new_t == 0 ) {
                goto error;
            }
            t = new_t;
            if( c == '\n' ) {
                t = tree;
            }
            break;
        default:
            if( size <= index + 1 ) {
                int new_size = size + 32;
                char *new_dirname = realloc( dirname, size );
                if( new_dirname == 0 ) {
                    goto error;
                }
                size = new_size;
                dirname = new_dirname;
            }
            dirname[index] = c;
            index++;
        }
    }
    free( dirname );
    dump_node( tree );
    delete_node( tree );
    return EXIT_SUCCESS;
error:
    fprintf( stderr, "No Memory\n" );
    exit( EXIT_FAILURE );
}

struct Node *new_node( char *content ) {
    struct Node *node = malloc( sizeof( struct Node ) );
    if( node == 0 ) {
        return 0;
    }
    node->content_size = strlen( content ) + 1;
    node->content = malloc( node->content_size );
    if( node->content == 0 ) {
        free( node );
        return 0;
    }
    strcpy( node->content, content );
    node->children_size = 1;
    node->num_children = 0;
    node->children = calloc( node->children_size, sizeof( struct Node ) );
    if( node->children == 0 ) {
        free( node );
        return 0;
    }
    return node;
}

struct Node *add_node_child( struct Node *node, char *content ) {
    struct Node *child_node = 0;
    int new_num_children = node->num_children + 1;
    if( node->children_size < new_num_children ) {
        struct Node **new_children;
        new_children = realloc( node->children, new_num_children * sizeof( struct Node ) );
        if( new_children == 0 ) {
            return 0;
        } else {
            node->children = new_children;
            node->children_size = new_num_children;
        }
    }
    child_node = new_node( content );
    if( child_node == 0 ) {
        return 0;
    }
    node->children[node->num_children] = child_node;
    node->num_children = new_num_children;
    return child_node;
}

struct Node *search_node_child( struct Node *node, char *content ) {
    int i;
    for( i = 0; i < node->num_children; i++ ) {
        struct Node *child = node->children[i];
        if( strcmp( child->content, content ) == 0 ) {
            return child;
        }
    }
    return 0;
}

void dump_node_iter( struct Node *node, int level ) {
    int i;
    if( level != 0 ) {
        for( i = 0; i < level; i++ ) {
            printf( "  " );
        }
        printf( "┗" );
    }
    printf( "%s\n", node->content );
    for( i = 0; i < node->num_children; i++ ) {
        dump_node_iter( node->children[i], level + 1 );
    }
}

void dump_node( struct Node *node ) {
    dump_node_iter( node, 0 );
}

void delete_node( struct Node *node ) {
    int i = 0;
    for( i = 0; i < node->num_children; i++ ) {
        delete_node( node->children[i] );
    }
    free( node->children );
    free( node->content );
    free( node );
}

Index

Feed

Other

Link

Pathtraq

loading...