forked from fmela/libdict
-
Notifications
You must be signed in to change notification settings - Fork 0
/
anagram.c
120 lines (103 loc) · 2.23 KB
/
anagram.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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "dict.h"
#include "dict_private.h"
void *xmalloc(size_t size);
char *xstrdup(const char *s);
typedef struct WordList WordList;
struct WordList {
char *word;
WordList *next;
};
int
main(int argc, char *argv[])
{
if (argc != 2) {
printf("Expected filename argument.\n");
exit(1);
}
FILE *fp = fopen(argv[1], "r");
if (!fp) {
printf("Unable to open file '%s'.\n", argv[1]);
exit(1);
}
rb_tree *tree = rb_tree_new(dict_str_cmp, NULL);
char buf[512];
while (fgets(buf, sizeof(buf), fp)) {
if (isupper(buf[0])) /* Disregard proper nouns. */
continue;
strtok(buf, "\r\n");
int freq[256] = { 0 };
memset(freq, 0, sizeof(freq));
ASSERT(buf[0] != '\0');
for (char *p = buf; *p; p++)
freq[tolower(*p)]++;
char name[1024];
char *p = name;
for (int i=1; i<256; i++) {
if (freq[i]) {
ASSERT(freq[i] < 10);
*p++ = i;
*p++ = '0' + freq[i];
}
}
*p = 0;
WordList *word = xmalloc(sizeof(*word));
word->word = xstrdup(buf);
WordList **wordp = NULL;
if (rb_tree_insert(tree, xstrdup(name), (void ***)&wordp)) {
ASSERT(*wordp == NULL);
} else {
/* Key already exists. */
ASSERT(wordp != NULL);
}
word->next = *wordp;
*wordp = word;
}
rb_itor *itor = rb_itor_new(tree);
for (rb_itor_first(itor); rb_itor_valid(itor); rb_itor_next(itor)) {
WordList *word = rb_itor_data(itor);
ASSERT(word != NULL);
if (word->next) {
int count = 1;
while (word->next)
count++, word = word->next;
printf("%2d:[", count);
word = rb_itor_data(itor);
while (word) {
printf("%s%c", word->word, word->next ? ',' : ']');
word = word->next;
}
printf("\n");
}
word = rb_itor_data(itor);
while (word) {
WordList *next = word->next;
free(word->word);
free(word);
word = next;
}
} while (rb_itor_next(itor));
rb_itor_free(itor);
rb_tree_free(tree);
return 0;
}
char *
xstrdup(const char *s)
{
size_t len = strlen(s) + 1;
return memcpy(xmalloc(len), s, len);
}
void *
xmalloc(size_t size)
{
ASSERT(size > 0);
void *p = malloc(size);
if (!p) {
fprintf(stderr, "Out of memory\n");
abort();
}
return p;
}