struct key {
       char *word;
       int count;
   } keytab[NKEYS];


   struct key {
       char *word;
       int count;
   };

   struct key keytab[NKEYS];


   struct key {
       char *word;
       int count;
   } keytab[] = {
       "auto", 0,
       "break", 0,
       "case", 0,
       "char", 0,
       "const", 0,
       "continue", 0,
       "default", 0,
       /* ... */
       "unsigned", 0,
       "void", 0,
       "volatile", 0,
       "while", 0
   };


   #include <stdio.h>
   #include <ctype.h>
   #include <string.h>

   #define MAXWORD 100

   int getword(char *, int);
   int binsearch(char *, struct key *, int);

   /* count C keywords */
   main()
   {
       int n;
       char word[MAXWORD];

       while (getword(word, MAXWORD) != EOF)
           if (isalpha(word[0]))
               if ((n = binsearch(word, keytab, NKEYS)) >= 0)
                   keytab[n].count++;
       for (n = 0; n < NKEYS; n++)
           if (keytab[n].count > 0)
               printf("%4d %s\n",
                   keytab[n].count, keytab[n].word);
       return 0;
   }

   /* binsearch:  find word in tab[0]...tab[n-1] */
   int binsearch(char *word, struct key tab[], int n)
   {
       int cond;
       int low, high, mid;

       low = 0;
       high = n - 1;
       while (low <= high) {
           mid = (low+high) / 2;
           if ((cond = strcmp(word, tab[mid].word)) < 0)
               high = mid - 1;
           else if (cond > 0)
               low = mid + 1;
           else
               return mid;
       }
       return -1;
   }


   /* getword:  get next word or character from input */
   int getword(char *word, int lim)
   {
       int c, getch(void);
       void ungetch(int);
       char *w = word;

       while (isspace(c = getch()))
           ;
       if (c != EOF)
           *w++ = c;
       if (!isalpha(c)) {
           *w = '\0';
           return c;
       }
       for ( ; --lim > 0; w++)
           if (!isalnum(*w = getch())) {
               ungetch(*w);
               break;
           }
       *w = '\0';
       return word[0];
   }


   #include <stdio.h>
   #include <ctype.h>
   #include <string.h>
   #define MAXWORD 100

   int getword(char *, int);
   struct key *binsearch(char *, struct key *, int);

   /* count C keywords; pointer version */
   main()
   {
       char word[MAXWORD];
       struct key *p;

       while (getword(word, MAXWORD) != EOF)
           if (isalpha(word[0]))
               if ((p=binsearch(word, keytab, NKEYS)) != NULL)
                   p->count++;
       for (p = keytab; p < keytab + NKEYS; p++)
           if (p->count > 0)
               printf("%4d %s\n", p->count, p->word);
       return 0;
   }

   /* binsearch: find word in tab[0]...tab[n-1] */
   struct key *binsearch(char *word, struck key *tab, int n)
   {
       int cond;
       struct key *low = &tab[0];
       struct key *high = &tab[n];
       struct key *mid;

       while (low < high) {
           mid = low + (high-low) / 2;
           if ((cond = strcmp(word, mid->word)) < 0)
               high = mid;
           else if (cond > 0)
               low = mid + 1;
           else
               return mid;
       }
       return NULL;
   }

   struct tnode {     /* the tree node: */
       char *word;           /* points to the text */
       int count;            /* number of occurrences */
       struct tnode *left;   /* left child */
       struct tnode *right;  /* right child */
   };


   #include <stdio.h>
   #include <ctype.h>
   #include <string.h>

   #define MAXWORD 100
   struct tnode *addtree(struct tnode *, char *);
   void treeprint(struct tnode *);
   int getword(char *, int);

   /* word frequency count */
   main()
   {
       struct tnode *root;
       char word[MAXWORD];

       root = NULL;
       while (getword(word, MAXWORD) != EOF)
           if (isalpha(word[0]))
               root = addtree(root, word);
       treeprint(root);
       return 0;
   }
   struct tnode *talloc(void);
   char *strdup(char *);

   /* addtree:  add a node with w, at or below p */
   struct treenode *addtree(struct tnode *p, char *w)
   {
       int cond;

       if (p == NULL) {     /* a new word has arrived */
           p = talloc();    /* make a new node */
           p->word = strdup(w);
           p->count = 1;
           p->left = p->right = NULL;
       } else if ((cond = strcmp(w, p->word)) == 0)
           p->count++;      /* repeated word */
       else if (cond < 0)   /* less than into left subtree */
           p->left = addtree(p->left, w);
       else             /* greater than into right subtree */
           p->right = addtree(p->right, w);
       return p;
   }
   /* treeprint:  in-order print of tree p */
   void treeprint(struct tnode *p)
   {
       if (p != NULL) {
           treeprint(p->left);
           printf("%4d %s\n", p->count, p->word);
           treeprint(p->right);
       }
   }

   #include <stdlib.h>

   /* talloc:  make a tnode */
   struct tnode *talloc(void)
   {
       return (struct tnode *) malloc(sizeof(struct tnode));
   }
   char *strdup(char *s)   /* make a duplicate of s */
   {
       char *p;

       p = (char *) malloc(strlen(s)+1); /* +1 for '\0' */
       if (p != NULL)
           strcpy(p, s);
       return p;
   }


   struct nlist {       /* table entry: */
       struct nlist *next;   /* next entry in chain */
       char *name;           /* defined name */
       char *defn;           /* replacement text */
   };


   #define HASHSIZE 101

   static struct nlist *hashtab[HASHSIZE];  /* pointer table */


   /* hash:  form hash value for string s */
   unsigned hash(char *s)
   {
       unsigned hashval;

       for (hashval = 0; *s != '\0'; s++)
           hashval = *s + 31 * hashval;
       return hashval % HASHSIZE;
   }


   /* lookup:  look for s in hashtab */
   struct nlist *lookup(char *s)
   {
       struct nlist *np;

       for (np = hashtab[hash(s)];  np != NULL; np = np->next)
           if (strcmp(s, np->name) == 0)
               return np;     /* found */
       return NULL;           /* not found */
   }


   struct nlist *lookup(char *);
   char *strdup(char *);

   /* install:  put (name, defn) in hashtab */
   struct nlist *install(char *name, char *defn)
   {
       struct nlist *np;
       unsigned hashval;

       if ((np = lookup(name)) == NULL) { /* not found */
           np = (struct nlist *) malloc(sizeof(*np));
           if (np == NULL || (np->name = strdup(name)) == NULL)
               return NULL;
           hashval = hash(name);
           np->next = hashtab[hashval];
           hashtab[hashval] = np;
       } else       /* already there */
           free((void *) np->defn);   /*free previous defn */
       if ((np->defn = strdup(defn)) == NULL)
           return NULL;
       return np;
   }


   typedef struct tnode *Treeptr;

   typedef struct tnode { /* the tree node: */
       char *word;           /* points to the text */
       int count;            /* number of occurrences */
       struct tnode *left;   /* left child */
       struct tnode *right;  /* right child */
   } Treenode;
   Treeptr talloc(void)
   {
       return (Treeptr) malloc(sizeof(Treenode));
   }