開発環境
- OS X Lion - Apple(OS)
- Emacs、BBEdit - Bare Bones Software, Inc. (Text Editor)
- プログラミング言語: C
- Clang (コンパイラ)
プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第6章(構造体)、6.4(構造体へのポインタ)、6.5(自己参照的構造体)、演習6-3を解いてみる。
その他参考書籍
- プログラミング言語Cアンサー・ブック 第2版 (クロビス・L.トンド、スコット・E.ギンペル(著)、矢吹 道郎(翻訳))
演習 6-3.
コード
sample.c
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #define MAXWORD 100 struct linked_list{ int line_number; struct linked_list *p; }; struct tnode { char *word; struct linked_list *line_numbers; struct tnode *left; struct tnode *right; }; struct tnode *addtree(struct tnode *, char *, int); void treeprint(struct tnode *); int getword(char *, int); int noise_word(char *); int main(int argc, char *argv[]) { struct tnode *root; char word[MAXWORD]; int line_number; line_number = 1; root = NULL; while (getword(word, MAXWORD) != EOF) { if (isalpha(word[0]) && noise_word(word) == -1) { root = addtree(root, word, line_number); } else if (word[0] == '\n') { line_number++; } } treeprint(root); return 0; } struct tnode *talloc(void); struct linked_list *lalloc(void); void add_line_number(struct tnode *, int); struct tnode *addtree(struct tnode *p, char *w, int line_number) { int cond; if (p == NULL) { p = talloc(); p->word = strdup(w); p->line_numbers = lalloc(); p->line_numbers->line_number = line_number; p->line_numbers->p = NULL; p->left = p->right = NULL; } else if ((cond = strcmp(w, p->word)) == 0) { add_line_number(p, line_number); } else if (cond < 0) { p->left = addtree(p->left, w, line_number); } else if(cond > 0) { p->right = addtree(p->right, w, line_number); } return p; } void add_line_number(struct tnode *p, int line_number) { struct linked_list *tmp; tmp = p->line_numbers; while (tmp->p != NULL && tmp->line_number != line_number) { tmp = tmp->p; } if (tmp->line_number != line_number) { tmp->p = lalloc(); tmp->p->line_number = line_number; tmp->p->p = NULL; } } struct tnode *talloc(void) { return (struct tnode *) malloc(sizeof(struct tnode)); } struct linked_list *lalloc(void) { return (struct linked_list *) malloc(sizeof(struct linked_list)); } void treeprint(struct tnode *p) { struct linked_list *tmp; if (p != NULL) { treeprint(p->left); printf("%s: ", p->word); for (tmp = p->line_numbers; tmp != NULL; tmp = tmp->p) { printf("%d ", tmp->line_number); } printf("\n"); treeprint(p->right); } } int getword(char *word, int lim) { int c, d, getch(void), skipcomment(); void ungetch(int); char *w = word; while (isspace(c = getch()) && c != '\n') ; if (c != EOF) { *w++ = c; } if (isalpha(c) || c == '_' || c == '#') { for (; --lim > 0; w++) { if (!isalnum(*w = getch())) { ungetch(*w); break; } } } *w = '\0'; return c; } int noise_word(char *w) { /* https://drupal.org/node/1202 のNoise Words Listより */ char *noise_word[] = { "$", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "about", "after", "all", "also", "an", "and", "another", "any", "are", "as", "at", "be", "because", "been", "before", "being", "between", "both", "but", "by", "c", "came", "can", "come", "could", "d", "did", "do", "e", "each", "f", "for", "from", "g", "get", "got", "h", "had", "has", "have", "he", "her", "here", "him", "himself", "his", "how", "i", "if", "in", "into", "is", "it", "j", "k", "l", "like", "make", "m", "many", "me", "might", "more", "most", "much", "must", "my", "n", "never", "now", "o", "of", "on", "only", "or", "other", "our", "out", "over", "p", "q", "r", "s", "said", "same", "see", "should", "since", "some", "still", "such", "t", "take", "than", "that", "the", "their", "them", "then", "there", "these", "they", "this", "those", "through", "to", "too", "u", "under", "up", "very", "v", "w", "was", "way", "we", "well", "were", "what", "where", "which", "while", "who", "with", "would", "x", "y", "you", "your", "z" }; int cond, mid; int low = 0; int high = sizeof(noise_word) / sizeof(char *) - 1; while (low <= high) { mid = (low + high) / 2; if ((cond = strcmp(w, noise_word[mid])) < 0) { high = mid - 1; } else if (cond > 0) { low = mid + 1; } else { return mid; } } return -1; } #define BUFSIZE 100 char buf[BUFSIZE]; int bufp = 0; int getch(void) { return (bufp > 0) ? buf[--bufp] : getchar(); } void ungetch(int c) { if (bufp >= BUFSIZE) { printf("ungetch: too many characters\n"); } else { buf[bufp++] = c; } }
入出力結果(Terminal)
$ curl http://www.example.com | ./a.out % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1270 100 1270 0 0 1245 0 0:00:01 0:00:01 --:--:-- 1788 Arial: 14 Content: 7 Domain: 4 44 Example: 4 44 Helvetica: 14 More: 47 Neue: 14 Open: 14 Sans: 14 This: 45 You: 45 asking: 46 auto: 19 33 34 background: 11 21 30 body: 10 29 42 49 border: 22 35 charset: 6 7 color: 11 21 25 30 content: 7 8 coordination: 46 css: 9 decoration: 26 device: 8 div: 17 32 43 48 doctype: 1 documents: 45 domain: 45 46 domains: 47 em: 19 22 36 equiv: 7 established: 45 example: 47 examples: 45 46 family: 14 font: 14 h1: 44 head: 3 40 href: 47 html: 1 2 7 50 http: 7 47 iana: 47 illustrative: 45 information: 47 initial: 8 link: 24 margin: 12 19 34 max: 28 may: 45 media: 28 meta: 6 7 8 name: 8 none: 26 org: 47 padding: 13 20 36 permission: 46 prior: 46 px: 18 20 28 radius: 22 35 sans: 14 scale: 8 serif: 14 style: 9 39 text: 7 9 26 title: 4 type: 7 9 use: 45 used: 45 utf: 6 7 viewport: 8 visited: 24 width: 8 18 28 33 without: 46 www: 47 $
0 コメント:
コメントを投稿