Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.21 KB | None | 0 0
  1. /* Copyright (C) 1999 Lucent Technologies */
  2. /* Excerpted from 'The Practice of Programming' */
  3. /* by Brian W. Kernighan and Rob Pike */
  4.  
  5. /*
  6. * Markov chain random text generator.
  7. */
  8.  
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <time.h>
  14. #include "eprintf.h"
  15.  
  16. enum {
  17. NPREF = 2, /* number of prefix words */
  18. NHASH = 4093, /* size of state hash table array */
  19. MAXGEN = 10000 /* maximum words generated */
  20. };
  21.  
  22. typedef struct State State;
  23. typedef struct Suffix Suffix;
  24.  
  25. struct State { /* prefix + suffix list */
  26. char *pref[NPREF]; /* prefix words */
  27. Suffix *suf; /* list of suffixes */
  28. State *next; /* next in hash table */
  29. };
  30.  
  31. struct Suffix { /* list of suffixes */
  32. char *word; /* suffix */
  33. Suffix *next; /* next in list of suffixes */
  34. };
  35.  
  36. State *lookup(char *prefix[], int create);
  37. void build(char *prefix[], FILE*);
  38. void generate(int nwords);
  39. void add(char *prefix[], char *word);
  40.  
  41. State *statetab[NHASH]; /* hash table of states */
  42.  
  43. char NONWORD[] = "\n"; /* cannot appear as real word */
  44.  
  45. /* markov main: markov-chain random text generation */
  46. int main(void)
  47. {
  48. int i, nwords = MAXGEN;
  49. char *prefix[NPREF]; /* current input prefix */
  50.  
  51. int c;
  52. long seed;
  53. seed = time(NULL);
  54.  
  55. setprogname("markov");
  56.  
  57. srand(seed);
  58. for (i = 0; i < NPREF; i++) /* set up initial prefix */
  59. prefix[i] = NONWORD;
  60. build(prefix, stdin);
  61. add(prefix, NONWORD);
  62. generate(nwords);
  63. return 0;
  64. }
  65.  
  66. const int MULTIPLIER = 31; /* for hash() */
  67.  
  68. /* hash: compute hash value for array of NPREF strings */
  69. unsigned int hash(char *s[NPREF])
  70. {
  71. unsigned int h;
  72. unsigned char *p;
  73. int i;
  74.  
  75. h = 0;
  76. for (i = 0; i < NPREF; i++)
  77. for (p = (unsigned char *) s[i]; *p != '\0'; p++)
  78. h = MULTIPLIER * h + *p;
  79. return h % NHASH;
  80. }
  81.  
  82. /* lookup: search for prefix; create if requested. */
  83. /* returns pointer if present or created; NULL if not. */
  84. /* creation doesn't strdup so strings mustn't change later. */
  85. State* lookup(char *prefix[NPREF], int create)
  86. {
  87. int i, h;
  88. State *sp;
  89.  
  90. h = hash(prefix);
  91. for (sp = statetab[h]; sp != NULL; sp = sp->next) {
  92. for (i = 0; i < NPREF; i++)
  93. if (strcmp(prefix[i], sp->pref[i]) != 0)
  94. break;
  95. if (i == NPREF) /* found it */
  96. return sp;
  97. }
  98. if (create) {
  99. sp = (State *) emalloc(sizeof(State));
  100. for (i = 0; i < NPREF; i++)
  101. sp->pref[i] = prefix[i];
  102. sp->suf = NULL;
  103. sp->next = statetab[h];
  104. statetab[h] = sp;
  105. }
  106. return sp;
  107. }
  108.  
  109. /* addsuffix: add to state. suffix must not change later */
  110. void addsuffix(State *sp, char *suffix)
  111. {
  112. Suffix *suf;
  113.  
  114. suf = (Suffix *) emalloc(sizeof(Suffix));
  115. suf->word = suffix;
  116. suf->next = sp->suf;
  117. sp->suf = suf;
  118. }
  119.  
  120. /* add: add word to suffix list, update prefix */
  121. void add(char *prefix[NPREF], char *suffix)
  122. {
  123. State *sp;
  124.  
  125. sp = lookup(prefix, 1); /* create if not found */
  126. addsuffix(sp, suffix);
  127. /* move the words down the prefix */
  128. memmove(prefix, prefix+1, (NPREF-1)*sizeof(prefix[0]));
  129. prefix[NPREF-1] = suffix;
  130. }
  131.  
  132. /* build: read input, build prefix table */
  133. void build(char *prefix[NPREF], FILE *f)
  134. {
  135. char buf[100], fmt[10];
  136.  
  137. /* create a format string; %s could overflow buf */
  138. sprintf(fmt, "%%%ds", sizeof(buf)-1);
  139. while (fscanf(f, fmt, buf) != EOF)
  140. add(prefix, estrdup(buf));
  141. }
  142.  
  143. /* generate: produce output, one word per line */
  144. void generate(int nwords)
  145. {
  146. FILE *fin = fopen("rands.txt", "r");
  147. int a[10000];
  148. int j = 0;
  149. int value;
  150. char line[10];
  151.  
  152. while (fgets(line,10,fin)!=NULL)
  153. {
  154. sscanf(line,"%f", &value);
  155. a[j] = value;
  156. j++;
  157. }
  158.  
  159. State *sp;
  160. Suffix *suf;
  161. char *prefix[NPREF], *w;
  162. int i, nmatch, k;
  163.  
  164. for (i = 0; i < NPREF; i++) /* reset initial prefix */
  165. prefix[i] = NONWORD;
  166.  
  167. for (i = 0; i < nwords; i++) {
  168. sp = lookup(prefix, 0);
  169. if (sp == NULL)
  170. eprintf("internal error: lookup failed");
  171. nmatch = 0;
  172. for (suf = sp->suf; suf != NULL; suf = suf->next)
  173. if (a[i] % ++nmatch == 0) /* prob = 1/nmatch */
  174. w = suf->word;
  175. if (nmatch == 0)
  176. eprintf("internal error: no suffix %d %s", i, prefix[0]);
  177. if (strcmp(w, NONWORD) == 0)
  178. break;
  179. printf("%s\n", w);
  180. memmove(prefix, prefix+1, (NPREF-1)*sizeof(prefix[0]));
  181. prefix[NPREF-1] = w;
  182. }
  183. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement