|
|
1.1 ! root 1: /* wf1 - print word frequencies; uses structures */ ! 2: ! 3: struct node { ! 4: int count; /* frequency count */ ! 5: struct node *left; /* left subtree */ ! 6: struct node *right; /* right subtree */ ! 7: char *word; /* word itself */ ! 8: } words[2000]; ! 9: int next; /* index of next free entry in words */ ! 10: ! 11: struct node *lookup(); ! 12: ! 13: main() ! 14: { ! 15: struct node *root; ! 16: char word[20]; ! 17: ! 18: root = 0; ! 19: next = 0; ! 20: while (getword(word)) ! 21: lookup(word, &root)->count++; ! 22: tprint(root); ! 23: return 0; ! 24: } ! 25: ! 26: /* err - print error message s and die */ ! 27: err(s) ! 28: char *s; ! 29: { ! 30: printf("? %s\n", s); ! 31: exit(1); ! 32: } ! 33: ! 34: /* getword - get next input word into buf, return 0 on EOF */ ! 35: int getword(buf) ! 36: char *buf; ! 37: { ! 38: char *s; ! 39: int c; ! 40: ! 41: while ((c = getchar()) != -1 && isletter(c) == 0) ! 42: ; ! 43: for (s = buf; c = isletter(c); c = getchar()) ! 44: *s++ = c; ! 45: *s = 0; ! 46: if (s > buf) ! 47: return (1); ! 48: return (0); ! 49: } ! 50: ! 51: /* isletter - return folded version of c if it is a letter, 0 otherwise */ ! 52: int isletter(c) ! 53: int c; ! 54: { ! 55: if (c >= 'A' && c <= 'Z') ! 56: c += 'a' - 'A'; ! 57: if (c >= 'a' && c <= 'z') ! 58: return (c); ! 59: return (0); ! 60: } ! 61: ! 62: /* lookup - lookup word in tree; install if necessary */ ! 63: struct node *lookup(word, p) ! 64: char *word; ! 65: struct node **p; ! 66: { ! 67: int cond; ! 68: char *malloc(); ! 69: ! 70: if (*p) { ! 71: cond = strcmp(word, (*p)->word); ! 72: if (cond < 0) ! 73: return lookup(word, &(*p)->left); ! 74: else if (cond > 0) ! 75: return lookup(word, &(*p)->right); ! 76: else ! 77: return *p; ! 78: } ! 79: if (next >= 2000) ! 80: err("out of node storage"); ! 81: words[next].count = 0; ! 82: words[next].left = words[next].right = 0; ! 83: words[next].word = malloc(strlen(word) + 1); ! 84: if (words[next].word == 0) ! 85: err("out of word storage"); ! 86: strcpy(words[next].word, word); ! 87: return *p = &words[next++]; ! 88: } ! 89: ! 90: /* tprint - print tree */ ! 91: tprint(tree) ! 92: struct node *tree; ! 93: { ! 94: if (tree) { ! 95: tprint(tree->left); ! 96: printf("%d\t%s\n", tree->count, tree->word); ! 97: tprint(tree->right); ! 98: } ! 99: } ! 100: ! 101: /* strcmp - compare s1 and s2, return <0, 0, or >0 */ ! 102: int strcmp(s1, s2) ! 103: char *s1, *s2; ! 104: { ! 105: while (*s1 == *s2) { ! 106: if (*s1++ == 0) ! 107: return 0; ! 108: ++s2; ! 109: } ! 110: if (*s1 == 0) ! 111: return -1; ! 112: else if (*s2 == 0) ! 113: return 1; ! 114: return *s1 - *s2; ! 115: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.