6
6
* By Faisal Saadatmand
7
7
*/
8
8
9
- #include <stdio.h>
10
- #include <string.h>
11
9
#include <ctype.h>
10
+ #include <stdio.h>
12
11
#include <stdlib.h>
12
+ #include <string.h>
13
13
14
14
#define MAXWORD 100
15
15
#define BUFSIZE 100
16
16
#define NKEYS (sizeof noisetab / sizeof noisetab[0])
17
17
18
+ /* types */
19
+ struct list {
20
+ int number ;
21
+ struct list * next ;
22
+ };
23
+
18
24
struct tnode {
19
25
char * word ;
20
- struct list * line ;
21
- int count ;
26
+ struct list * lines ;
22
27
struct tnode * left ;
23
28
struct tnode * right ;
24
29
};
25
30
26
- struct list {
27
- int number ;
28
- struct list * next ;
29
- };
30
-
31
31
struct key {
32
32
char * word ;
33
33
int count ;
34
34
};
35
35
36
+ /* functions */
37
+ int getword (char * , int );
38
+ struct tnode * talloc (void ); /* allocate memory to new tree node */
39
+ char * strDup (char * ); /* copy string into safe place */
40
+ struct tnode * addtree (struct tnode * , char * , int );
41
+ void treeprint (struct tnode * );
42
+ void printList (struct list * );
43
+ struct key * binsearch (char * , struct key * , int );
44
+ void freetree (struct tnode * );
45
+
46
+ /* globals */
47
+ int buf [BUFSIZE ]; /* buffer from ungetch */
48
+ int bufp = 0 ; /* next free position in buf */
49
+
36
50
struct key noisetab [] = {
37
51
{ "a" , 0 },
38
52
{ "and" , 0 },
@@ -46,38 +60,22 @@ struct key noisetab[] = {
46
60
{ "with" , 0 },
47
61
};
48
62
49
- /* functions */
50
- int getword (char * , int , int * );
51
- struct tnode * talloc (void ); /* allocate memory to new tree node */
52
- char * strDup (char * ); /* copy string into safe place */
53
- struct tnode * addtree (struct tnode * , char * , int );
54
- void treeprint (struct tnode * );
55
- void printList (struct list * );
56
- struct key * binsearch (char * , struct key * , int );
57
- struct tnode * freetree (struct tnode * );
58
- struct list * freelist (struct list * );
59
-
60
- /* globals */
61
- int buf [BUFSIZE ]; /* buffer from ungetch */
62
- int bufp = 0 ; /* next free position in buf */
63
-
64
63
/* getword: get next word or character from input */
65
- int getword (char * word , int lim , int * ln )
64
+ int getword (char * word , int lim )
66
65
{
67
66
int c , getch (void );
68
67
void ungetch (int );
69
68
char * w = word ;
70
69
71
- while (isspace (c = getch ()))
72
- if (c == '\n' )
73
- (* ln )++ ;
70
+ while (isblank (c = getch ()))
71
+ ;
74
72
if (c != EOF )
75
73
* w ++ = c ;
76
74
if (!isalpha (c )) {
77
75
* w = '\0' ;
78
76
return c ;
79
77
}
80
- for ( ; -- lim > 0 ; w ++ )
78
+ for ( ; -- lim > 0 ; ++ w )
81
79
if (!isalnum (* w = getch ())) {
82
80
ungetch (* w );
83
81
break ;
@@ -86,12 +84,14 @@ int getword(char *word, int lim, int *ln)
86
84
return word [0 ];
87
85
}
88
86
89
- int getch (void ) /* get a (possibly pushed back) character */
87
+ /* get a (possibly pushed back) character */
88
+ int getch (void )
90
89
{
91
90
return (bufp > 0 ) ? buf [-- bufp ] : getchar ();
92
91
}
93
92
94
- void ungetch (int c ) /* push character back on input */
93
+ /* push character back on input */
94
+ void ungetch (int c )
95
95
{
96
96
if (bufp >= BUFSIZE )
97
97
printf ("ungetch: too many characters\n" );
@@ -119,13 +119,12 @@ char *strDup(char *s)
119
119
/* addList: add a node with ln, at or before p */
120
120
struct list * addlist (struct list * p , int ln )
121
121
{
122
- if (p == NULL ) {
122
+ if (! p ) {
123
123
p = malloc (sizeof (struct list ));
124
124
p -> number = ln ;
125
125
p -> next = NULL ;
126
126
} else if (p -> number != ln ) /* skip multi-occurrence on same line */
127
127
p -> next = addlist (p -> next , ln );
128
-
129
128
return p ;
130
129
}
131
130
@@ -135,16 +134,14 @@ struct tnode *addtree(struct tnode *p, char *w, int ln)
135
134
int cond ;
136
135
struct list * first = NULL ;
137
136
138
- if (p == NULL ) { /* a new word has arrived */
137
+ if (! p ) { /* a new word has arrived */
139
138
p = talloc (); /* make a new node */
140
139
p -> word = strDup (w ); /* copy data to it */
141
- p -> count = 1 ;
142
- p -> line = addlist (first , ln );
140
+ p -> lines = addlist (first , ln );
143
141
p -> left = p -> right = NULL ;
144
- } else if ((cond = strcmp (w , p -> word )) == 0 ) {
145
- p -> count ++ ; /* repeated word */
146
- p -> line = addlist (p -> line , ln );
147
- } else if (cond < 0 ) /* less than into left subtree */
142
+ } else if (!(cond = strcmp (w , p -> word )))
143
+ p -> lines = addlist (p -> lines , ln );
144
+ else if (cond < 0 ) /* less than into left subtree */
148
145
p -> left = addtree (p -> left , w , ln );
149
146
else
150
147
p -> right = addtree (p -> right , w , ln );
@@ -154,22 +151,22 @@ struct tnode *addtree(struct tnode *p, char *w, int ln)
154
151
/* treeprint: in-order print of tree p */
155
152
void treeprint (struct tnode * p )
156
153
{
157
- if (p != NULL ) {
158
- treeprint ( p -> left ) ;
159
- printf ( "%4d %s " , p -> count , p -> word );
160
- printList ( p -> line );
161
- printf ( "\n" );
162
- treeprint ( p -> right );
163
- }
154
+ if (! p )
155
+ return ;
156
+ treeprint ( p -> left );
157
+ printf ( " %s " , p -> word );
158
+ printList ( p -> lines );
159
+ printf ( "\n" );
160
+ treeprint ( p -> right );
164
161
}
165
162
166
163
/* printList: preorder print of list p */
167
164
void printList (struct list * p )
168
165
{
169
- if (p != NULL ) {
170
- printf ( "%d " , p -> number ) ;
171
- printList ( p -> next );
172
- }
166
+ if (! p )
167
+ return ;
168
+ printf ( "%d " , p -> number );
169
+ printList ( p -> next );
173
170
}
174
171
175
172
/* binsearch: find word in tab[0]...tab[n - 1] */
@@ -193,43 +190,43 @@ struct key *binsearch(char *word, struct key *tab, int n)
193
190
}
194
191
195
192
/* freellist: frees allocated heap memory of linked list */
196
- struct list * freelist (struct list * node )
193
+ void freelist (struct list * node )
197
194
{
198
- if (node != NULL ) {
199
- freelist (node -> next );
200
- free (node );
201
- }
202
- return node ;
195
+ if (!node )
196
+ return ;
197
+ freelist (node -> next );
198
+ free (node );
203
199
}
204
200
205
201
/* freetree: frees allocated heap memory of tree */
206
- struct tnode * freetree (struct tnode * node )
202
+ void freetree (struct tnode * node )
207
203
{
208
- if (node != NULL ) {
209
- freetree (node -> left );
210
- freetree (node -> right );
211
- free (node -> word );
212
- freelist (node -> line ); /* delete linked list in nodes */
213
- free (node );
214
- }
215
- return node ;
204
+ void freelist (struct list * );
205
+
206
+ if (!node )
207
+ return ;
208
+ freetree (node -> left );
209
+ freetree (node -> right );
210
+ free (node -> word );
211
+ freelist (node -> lines ); /* delete linked list in nodes */
212
+ free (node );
216
213
}
217
214
218
215
int main (void )
219
216
{
220
217
struct tnode * root ; /* root node */
221
- struct key * sought ; /* currently sought after word */
222
218
char word [MAXWORD ]; /* currently read word */
223
- int lineNo = 1 ; /* currently searched line */
219
+ int lineno = 1 ; /* currently searched line */
224
220
225
221
root = NULL ;
226
- while (getword (word , MAXWORD , & lineNo ) != EOF ) {
227
- sought = binsearch (word , noisetab , NKEYS ); /* skip noise words */
228
- if ( isalpha ( word [ 0 ]) && ! sought )
229
- root = addtree ( root , word , lineNo );
230
- }
222
+ while (getword (word , MAXWORD ) != EOF )
223
+ if ( isalpha ( word [ 0 ]) && ! binsearch (word , noisetab , NKEYS ))
224
+ root = addtree ( root , word , lineno );
225
+ else if ( word [ 0 ] == '\n' )
226
+ ++ lineno ;
231
227
treeprint (root );
232
- root = freetree (root ); /* clean up */
228
+ /* clean up */
229
+ freetree (root );
233
230
root = NULL ;
234
231
return 0 ;
235
232
}
0 commit comments