|
> Word table[TABLE_SIZE];
表を順番に探索するのは時間が掛かるので、二分木にしてみました。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FNAME "file2.txt"
typedef struct Node Node;
struct Node {
char *word; int count;
Node *left, *right;
};
typedef struct {
Node *np; int count;
Node **sp; int index;
} Tree;
void *Malloc(size_t size)
{
void *p = malloc(size);
if (p == NULL) fprintf(stderr, "out of memory\n"), exit(1);
return p;
}
Tree *create_tree(void)
{
Tree *tp = Malloc(sizeof(Tree));
tp->np = NULL; tp->count = 0;
tp->sp = NULL; tp->index = 0;
return tp;
}
char *Strdup(const char *s)
{
return strcpy(Malloc(strlen(s) + 1), s);
}
void add_tree(Tree *tp, const char *word)
{
Node *np, **npp = &tp->np; int diff;
while (*npp) {
np = *npp;
diff = strcmp(word, np->word);
if (diff == 0) { np->count++; return; }
npp = (diff < 0) ? &np->left : &np->right;
}
np = Malloc(sizeof(Node));
np->word = Strdup(word);
np->count = 1;
np->left = np->right = NULL;
*npp = np;
tp->count++;
}
void add_node(Tree *tp, Node *np)
{
if (np == NULL) return;
add_node(tp, np->left);
tp->sp[tp->index++] = np;
add_node(tp, np->right);
}
int compare_tree(const void *a, const void *b)
{
Node **p1 = (Node **)a, **p2 = (Node **)b;
return (*p2)->count - (*p1)->count;
}
void sort_tree(Tree *tp)
{
tp->sp = Malloc(sizeof(Tree *) * tp->count);
add_node(tp, tp->np);
qsort(tp->sp, tp->count, sizeof(Tree *), compare_tree);
}
void print_tree(Tree *tp)
{
int i;
for (i = 0; i < tp->count; i++)
printf("%5d %s\n", tp->sp[i]->count, tp->sp[i]->word);
}
void free_node(Node *np)
{
if (np == NULL) return;
free_node(np->left);
free_node(np->right);
free(np);
}
void release_tree(Tree *tp)
{
free_node(tp->np);
free(tp);
}
int get_word(FILE *fp, char *word, int size)
{
int c, i = 0;
do {
if ((c = getc(fp)) == EOF) return EOF;
} while (! isalpha(c));
size--;
do {
if (i < size) word[i++] = tolower(c);
c = getc(fp);
} while (isalpha(c));
word[i] = '\0';
return i;
}
int main()
{
char word[128];
Tree *tp;
FILE *fp = fopen(FNAME, "r");
if (fp == NULL) return printf("can't open %s\n", FNAME), 1;
tp = create_tree();
while (get_word(fp, word, sizeof word) != EOF)
add_tree(tp, word);
sort_tree(tp);
print_tree(tp);
release_tree(tp);
return 0;
}
|