/* wordfreq.c; cpl6.5 */ #include #include #include /* for malloc() */ #define MAXWORD 100 char Switch(void*, void*); /* Return zero if first comes before second - non-zero otherwise */ void shellsort (void* v[], short n); long nodecount; struct tnode { /* the tree node */ char *word; /* points to the word */ short count; /* number of occurrences */ short Count; struct tnode *left; /* left branch */ struct tnode *right;/* right branch */ }; struct tnode *addtree(struct tnode *, char *); void treeprint(struct tnode *); struct tnode *talloc(void); char *strdup(char *); int getword(char *, int); void error(char *); char Strcmp(char *, char *); long node_Count(struct tnode*); void node_Pointer(struct tnode *,struct tnode**,long); /* word frequency count */ main() { struct tnode *root, ** nd; char word[MAXWORD]; short i; root = NULL; nodecount=0; while (getword(word, MAXWORD) != EOF) if (isalpha(word[0])) root = addtree(root,word); /* treeprint(root); */ printf("%d\n",nodecount); printf("%d\n",node_Count(root)); nd=(struct tnode**)malloc(sizeof(struct tnode*)*nodecount); node_Pointer(root,nd,0); shellsort((void*)nd,nodecount); for(i=0;iword, nd[i]->count,nd[i]->Count); return 0; } #define OK 0 #define NOTOK 1 char Switch(void* f, void *s) { struct tnode *F, *S; F=(struct tnode*)f; S=(struct tnode*)s; if( (F->count+F->Count) > (S->count+S->Count) ) return OK; else if ((F->count+F->Count)== (S->count+S->Count) && strcmp(F->word,S->word)<0) return OK; else return NOTOK; } long node_Count(struct tnode *p) { if(p==0) return 0; else return( node_Count(p->left)+1+node_Count(p->right)); } void node_Pointer(struct tnode* p, struct tnode **nd, long offset) { long LL; if(p==0) return; node_Pointer(p->left,nd,offset); LL=node_Count(p->left)+offset; nd[LL]=p; node_Pointer(p->right,nd,LL+1); } /* addtree: add a node with w, at or below p */ struct tnode *addtree(struct tnode *p, char *w) { int cond; if (p == NULL) { /* a new word has arrived */ nodecount++; p = talloc(); /* make a new node */ if (p == NULL) error("addtree: memory allocation failure"); p->word = strdup(w);/* copy new word to its own memory location */ if(w[0]<='Z') { p->count = 0; p->Count=1;} else {p->count=1; p->Count=0;} /* initialize count for new word */ p->left = p->right = NULL; /* new branches empty */ } else if ((cond = Strcmp(w, p->word)) == 0) if(w[0]<='Z') p->Count++; else p->count++; /* repeated word */ else if (cond < 0) /* into left branch */ p->left = addtree(p->left, w); else 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); if(p->count==0) printf("%s _ %d\n",p->word,p->Count); else if(p->Count==0) printf("%s %d _\n",p->word,p->count); else printf("%s %d %d\n", p->word, p->count, p->count); treeprint(p->right); } } /* 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; short i; p = (char *) malloc(strlen(s) + 1); /* +1 for '\0' */ if (p != NULL){ for(i=0; s[i]!=0;i++) if(s[i]<='Z') p[i]=s[i]+'a'-'A'; else p[i]=s[i]; p[i]=0; } else error("strdup: memory allocation failure"); return p; } /* getword: get next word or character from input */ int getword(char *word, int lim) { int c; char *w = word; while (isspace(c = getchar())) ; if (c != EOF) *w++ = c; if (!isalpha(c)) { *w = '\0'; return c; } for ( ; --lim > 0; w++) if (!isalnum(*w = getchar())) { ungetc(*w, stdin); break; } *w = '\0'; return word[0]; } void error(char *s) { printf("\n%s\n"); exit(1); } #define OOO 1 #define INORDER -1 char Strcmp(char *w, char *x) { char A; while (*w!=0 && *x!=0) { A=*w;if(A<='Z') A+='a'-'A'; if(A<*x) return INORDER; else if(A>*x) return OOO; w++;x++;} if(*w==*x) return 0; else if(*w!=0) return OOO; return INORDER; }