#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef LOOPCOUNT
#define LOOPCOUNT 1
#endif
typedef struct node_t {
int count;
struct node_t *ascii[256];
} node_t;
node_t *root;
int max_depth;
void show_list(node_t *node, char *word, int depth)
{
int i;
if (node->count) {
word[depth] = '\0';
for (i = 0; i < node->count; i++) {
puts(word);
}
}
for (i='a'; i <= 'z'; i++) {
if (node->ascii[i]) {
word[depth] = i;
show_list(node->ascii[i], word, depth+1);
}
}
for (i='A'; i <= 'Z'; i++) {
if (node->ascii[i]) {
word[depth] = i;
show_list(node->ascii[i], word, depth+1);
}
}
}
void show_list_reverse(node_t *node, char *word, int depth)
{
int i;
for (i='Z'; i >= 'A'; i--) {
if (node->ascii[i]) {
word[depth] = i;
show_list_reverse(node->ascii[i], word, depth+1);
}
}
for (i='z'; i >= 'a'; i--) {
if (node->ascii[i]) {
word[depth] = i;
show_list_reverse(node->ascii[i], word, depth+1);
}
}
if (node->count) {
word[depth] = '\0';
for (i = 0; i < node->count; i++) {
puts(word);
}
}
}
void free_node(node_t *node) {
int i=0;
for (i=0; i < sizeof(node->ascii)/sizeof(node->ascii[0]); i++) {
if (node->ascii[i]) {
free_node(node->ascii[i]);
}
}
free(node);
}
void insert_word(node_t *node, char *word, int depth)
{
if (*word == '\0') {
node->count++;
if (depth > max_depth) {
max_depth = depth;
}
return;
}
if (!node->ascii[(int)*word]) {
node->ascii[(int)*word] = (node_t *)calloc(1, sizeof(node_t));
}
insert_word(node->ascii[(int)*word], word + 1, depth + 1);
}
char *read_file(char *fname)
{
FILE *fp;
size_t filesize;
char *buff;
fp = fopen(fname, "rb");
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
buff = (char *)calloc(1, filesize + 1);
buff[filesize] = '\0';
fseek(fp, 0, SEEK_SET);
fread(buff, filesize, 1, fp);
fclose(fp);
return buff;
}
void task(char *fn, int is_asc)
{
char *buff;
char *token;
buff = read_file(fn);
root = (node_t *)calloc(1, sizeof(node_t));
token = strtok(buff, "\n");
while (token) {
insert_word(root, token, 0);
token = strtok(NULL, "\n");
}
{
char *word_buf = (char *)malloc(max_depth + 1);
if (is_asc) {
show_list(root, word_buf, 0);
} else {
show_list_reverse(root, word_buf, 0);
}
free(word_buf);
}
free_node(root);
free(buff);
}
int main(int argc, char **argv)
{
int is_asc = 1;
if (argc != 2 && argc != 3) {
fprintf(stderr, "USAGE: %s filename [desc]\n", argv[0]);
exit(EXIT_FAILURE);
}
is_asc = !(argc == 3 && !strcmp(argv[2], "desc"));
{
int loopcount;
for (loopcount=0; loopcount < LOOPCOUNT; loopcount++) {
task(argv[1], is_asc);
}
}
return 0;
}