lolamontes69

K+R Exercise6_3

Sep 25th, 2014
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.96 KB | None | 0 0
  1. /* Write a cross-referencer that prints a list of all words in a document, and for
  2.    each word, a list of the line numbers on which it occurs. Remove noise words
  3.    like 'the,' 'and,' and so on.  
  4.  
  5. TODO:
  6.  
  7.     1: Tokenizing  
  8.     2: Case-sensitivity of string checking routine.
  9.  
  10.  
  11. 1: A decent tokenizer to deal with apostrophed and hyphenated words
  12.    urls and emails.
  13.  
  14. 2: lower-case all words using the lower function below to convert whilst
  15.    adding the string letter by letter into a char array,just before the
  16.    following line, so that only lowercase are getting added to the tree.
  17.  
  18.             if((n=binsearch(word,keytab,NKEYS))<0) {
  19.  
  20.  
  21. lower: convert c to lower-case; ASCII only
  22. int lower(int c)
  23. {
  24.     if(c>=A && c<=Z)
  25.         return c + 'a' - 'A';
  26.     else
  27.         return c;
  28. }
  29. */
  30.  
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <ctype.h>
  35. #include <string.h>
  36.  
  37. #define BUFSIZE 1000
  38. #define MAXWORD 1000
  39. #define MAXLINES 1000
  40.  
  41. static char *keytab[] = { "a","about","above","after","again","all","also","am","an",
  42.                   "and","any","are","aren't","as","at","be","because","been",
  43.                   "before","being","below","between","both","but","by",
  44.                   "can't","cannot","could","couldn't","did","didn't","do",
  45.                   "does","doesn't","doing","don't","down","during","each",
  46.                   "even","every","few","for","from","further","had","hadn't",
  47.                   "has","hasn't","have","haven't","having","he","he'd","he'll",
  48.                   "he's","her","here","here's","hers","herself","him","himself",
  49.                   "his","how","how's","i","i'd","i'll","i'm","i've","if","in",
  50.                   "into","is","isn't","it","it's","its","itself","let's","me",
  51.                   "more","most","mustn't","my","myself","no","nor","not",
  52.                   "of","off","on","once","only","or","other","ought","our","ours",
  53.                   "out","over","own","said","same","say","says","shan't",
  54.                   "she","she'd","she'll","she's","should","shouldn't","so",
  55.                   "some","still","such","than","that","that's","the","their",
  56.                   "theirs","them","then","there","there's","these","they",
  57.                   "they'd","they'll","they're","they've","this","those",
  58.                   "through","to","too","under","until","up","very","was",
  59.                   "wasn't","we","we'd","we'll","we're","we've","were","weren't",
  60.                   "what","what's","when","when's","where","where's","which",
  61.                   "while","who","who's","whom","why","why's","will","with",
  62.                   "won't","would","wouldn't","you","you'd","you'll","you're",
  63.                   "you've","your","yours","yourself"
  64. };
  65.  
  66. #define NKEYS 178 /* space req between NKEYS ()*/
  67.  
  68. struct tnode {            /* the tree node:       */
  69.     char *word;           /* points to the text   */
  70.     int lines[MAXLINES];
  71.     int count;            /* number of occurances */
  72.     struct tnode *left;   /* left child           */
  73.     struct tnode *right;  /* right child          */
  74. };
  75.  
  76. void titleline(void);
  77. int binsearch(char *word, char *tab[], int n);
  78. struct tnode *addtree(struct tnode *, char *);
  79. void treeprint(struct tnode *);
  80. int getword(char *, int);
  81.  
  82. int getch(void);
  83. void ungetch(int c);
  84.  
  85. char buf[BUFSIZE];
  86. int bufp = 0;
  87. int linenum = 0;
  88. int lineflag = 0;
  89.  
  90.  
  91. /* word frequency count */
  92. main()
  93. {
  94.     int n;
  95.     struct tnode *root;
  96.     char word[MAXWORD];
  97.  
  98.     root = NULL; /* pointer to NULL */
  99.     while(getword(word, MAXWORD) != EOF)
  100.         if(isalpha(word[0])) {
  101.             if((n=binsearch(word,keytab,NKEYS))<0) {
  102.                 root = addtree(root, word);
  103.                 if(lineflag) {
  104.                     lineflag=0;
  105.                     linenum++;
  106.                 }
  107.             }
  108.             if(lineflag) {
  109.                 lineflag=0;
  110.                 linenum++;
  111.             }
  112.         }
  113.     titleline();
  114.     treeprint(root);
  115.     return 0;
  116. }
  117.  
  118. void titleline(void)
  119. {
  120.     puts("----------------------------");
  121.     printf("%-15s %s \n", "word", "line numbers");
  122.     puts("----------------------------");
  123. }
  124.  
  125.  
  126. /* binsearch: find word in tab[0]...tab[n-1] */
  127. int binsearch(char *word, char *tab[], int n)
  128. {
  129.     int cond;
  130.     int low, high, mid;
  131.  
  132.     low  = 0;
  133.     high = n-1;
  134.     while(low <= high) {
  135.         mid = (low+high)/2;
  136.         if((cond=strcmp(word,tab[mid])) < 0)       /* do a binary search amongst keywords */
  137.             high = mid-1;                          /* to see if word is amongst them      */
  138.         else if(cond>0)                            /* if so it returns its index          */
  139.             low=mid+1;
  140.         else
  141.             return mid;
  142.     }
  143.     return -1;
  144. }
  145.  
  146. struct tnode *talloc(void);
  147. char *strdup1(char *);
  148.  
  149. /* addtree: add a node with w, at or below p */
  150. struct tnode *addtree(struct tnode *p, char *w)
  151. {
  152.     int cond;
  153.  
  154.     if(p == NULL) {      /* a new word has arrived */
  155.         p=talloc();      /* make a new node        */
  156.         p->word  = strdup1(w);
  157.         p->lines[0]=linenum;
  158.         p->count = 0;
  159.         p->left  = p->right = NULL;
  160.     } else if ((cond = strcmp(w, p->word)) == 0) {
  161.         if(p->lines[p->count]!=linenum) {
  162.             p->count++;
  163.             p->lines[p->count]=linenum;
  164.         }
  165.     } else if(cond < 0)  /* less than into left subtree */
  166.         p->left  = addtree(p->left, w);
  167.     else                 /* greater than into right subtree */
  168.         p->right = addtree(p->right, w);
  169.     return p;
  170. }
  171.  
  172.  
  173. /* getword: get nextword or character from input */
  174. int getword(char *word, int lim)
  175. {
  176.     int c, getch(void);
  177.     void ungetch(int);
  178.     char *w = word;
  179.  
  180.     while(isspace(c=getch()))
  181.         ;
  182.     if(c!=EOF)
  183.         *w++ = c;
  184.     if(!isalpha(c)) {
  185.         if(c=='\n')
  186.             linenum++;
  187.         *w = '\0';
  188.         return c;
  189.     }
  190.     for( ; --lim > 0; w++)
  191.         if(!isalnum(*w=getch())) {
  192.             if(*w=='\n') lineflag=1;
  193.             ungetch(*w);            
  194.             break;
  195.         }
  196.     *w = '\0';
  197.     return word[0];
  198. }
  199.  
  200. /* get a (possibly pushed-back) character */
  201. int getch(void)
  202. {
  203.     return (bufp > 0) ? buf[--bufp] : getchar();
  204. }
  205.  
  206. /* push character back on input */
  207. void ungetch(int c)
  208. {
  209.     if(bufp >= BUFSIZE)
  210.         printf("ungetch: too many characters\n");
  211.     else
  212.         buf[bufp++] = c;
  213. }
  214.  
  215.  
  216. /* treeprint: in-order print of tree p */
  217. void treeprint(struct tnode *p)
  218. {
  219.     int i;
  220.  
  221.     if(p!=NULL) {
  222.         treeprint(p->left);
  223.         p->count--;
  224.         printf("%-15s", p->word);
  225.         for(i=0 ; i <= p->count+1; i++)
  226.             printf(" %3d",p->lines[i]);
  227.         printf("\n");
  228.         treeprint(p->right);
  229.     }
  230. }
  231.  
  232. /* talloc: make a tnode */
  233. struct tnode *talloc(void)
  234. {
  235.     return (struct tnode *) malloc(sizeof(struct tnode));
  236. }
  237.  
  238. char *strdup1(char *s) /* make a duplicate of s */
  239. {
  240.     char *p;
  241.  
  242.     p=(char *) malloc(strlen(s)+1); /* +1 for '\0' */
  243.     if(p!=NULL)
  244.         strcpy(p, s);
  245.     return p;
  246. }
Advertisement
Add Comment
Please, Sign In to add comment