开发者

markov chain testing and implementation

So, I want to read in a text file with random numbers and create the suffix list using those numbers. it basically needs to reproduce the text given in "alice30.txt" using the algorithm. The code that I have right now looks like this. It compiles fine but doesn't create an output file for me. I need to reverse the array of the suffix so the output is correct. any help will be greatly appreciated. i have declared all the necessary functions like emalloc in the eprint f header file.

 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
 #include "eprintf.h"

  enum {
NPREF   = 2,    /* number of prefix words */
NHASH   = 4093, /* size of state hash table array */
MAXGEN  = 10000 /* maximum words generated */
   };

 typedef struct State State;
 typedef struct Suffix Suffix;

    struct State {  /* prefix + suffix list */
char    *pref[NPREF];   /* prefix words */
Suffix  *suf;           /* list of suffixes */
State   *next;          /* next in hash table */
    };

   struct Suffix {  /* list of suffixes */
char    *word;          /* suffix */
Suffix  *next;          /* next in list of suffixes */
  };

 State  *lookup(char *prefix[], int create);
 void   build(char *prefix[], FILE* myfile); /*assing the input stream*/
 void       generate(int nwords, int random_num[], FILE* outfile);
  /* passing the array and the output stream*/
 void   add(char *prefix[], char *word);

 State  *statetab[NHASH];   /* hash table of states */

 char NONWORD[] = "\n";  /* cannot appear as real word */


  /* markov main: markov-chain random text generation */
 int main(void)
 {
int i, nwords = MAXGEN;
char *prefix[NPREF];        /* current input prefix */

FILE* random_reader;
FILE* myfile;
FILE* outfile;

int c;
int element;
int random_num[10000];
char* line;
int j=0;
random_reader = fopen("../random_num.txt","r");
myfile = fopen("../alice30.txt","r");
outfile = fopen("../output/markov_c_out.txt","w");
while(fgets(line,20,random_reader)!=NULL)
{
    sscanf(line,"%o",&element);
    random_num[j]= element;
    j++;
}

setprogname("markov");


for (i = 0; i < NPREF; i++) /* set up initial prefix */
    prefix[i] = NONWORD;
build(prefix, myfile);
add(prefix, NONWORD);
generate(nwords, random_num, outfile); // calling the updated function
return 0;
    }   

   const int MULTIPLIER = 31;  /* for hash() */

   /* hash: compute hash value for array of NPREF strings */
     unsigned int hash(char *s[NPREF])
   {
unsigned int h;
unsigned char *p;
int i;

h = 0;
for (i = 0; i < NPREF; i++)
    for (p = (unsigned char *) s[i]; *p != '\0'; p++)
        h = MULTIPLIER * h + *p;
return h % NHASH;
     }

  /* lookup: search for prefix; create if requested. */
   /*  returns pointer if present or created; NULL if not. */
     /*  creation doesn't strdup so strings mustn't change later. */
     State* lookup(char *prefix[NPREF], int create)
   {
int i, h;
State *sp;

h = hash(prefix);
for (sp = statetab[h]; sp != NULL; sp = sp->next) {
    for (i = 0; i < NPREF; i++)
        if (strcmp(prefix[i], sp->pref[i]) != 0)
            break;
    if (i == NPREF)     /* found it */
        return sp;
}
if (create) {
    sp = (State *) emalloc(sizeof(State));
    for (i = 0; i < NPREF; i++)
        sp->pref[i] = prefix[i];
    sp->suf = NULL;
    sp->next = statetab[h];
    statetab[h] = sp;
}
return sp;
      }

     /* addsuffix: add to state. suffix must not change later */
      void addsuffix(State *sp, char *suffix)
     {
Suffix *suf;

suf = (Suffix *) emalloc(sizeof(Suffix));
suf->word = suffix;
suf->next = sp->suf;
sp->suf = suf;
  }

     /* add: add word to suffix list, update prefix */
   void add(char *prefix[NPREF], char *suffix)
    {
State *sp;

sp = lookup(prefix, 1);  /* create if not found */
addsuffix(sp, suffix);
/* move the words down the prefix */
memmove(prefix, prefix+1, (NPREF-1)*sizeof(prefix[0]));
prefix[NPREF-1] = suffix;
        }

       /* build: read input, build prefix table */
         void build(char *prefix[NPREF], FILE *myfile)
        {
char buf[100], fmt[10];

/* create a format string; %s could overflow buf */
sprintf(fmt, "%%%ds", sizeof(buf)-1);
while (fscanf(myfile, fmt, buf) != EOF)
    add(prefix, estrdup(buf));
         }

       /* g开发者_JAVA技巧enerate: produce output, one word per line */
     void generate(int nwords, int random_num[], FILE* outfile)
     {
State *sp;
Suffix *suf;
char *prefix[NPREF], *w;
int i, nmatch;

for (i = 0; i < NPREF; i++) /* reset initial prefix */
    prefix[i] = NONWORD;

for (i = 0; i < nwords; i++) {
    sp = lookup(prefix, 0);
    if (sp == NULL)
        eprintf("internal error: lookup failed");
    nmatch = 0;
    for (suf = sp->suf; suf != NULL; suf = suf->next)
        if (random_num[i] % ++nmatch == 0) /*using the elements of the array  */
            w = suf->word;
    if (nmatch == 0)
        eprintf("internal error: no suffix %d %s", i, prefix[0]);
    if (strcmp(w, NONWORD) == 0)
        break;

    fprintf(outfile, w);
    memmove(prefix, prefix+1, (NPREF-1)*sizeof(prefix[0]));
    prefix[NPREF-1] = w;

}

}


You are passing fgets an uninitialized variable.

You declare this:

char* line;

and later call:

while(fgets(line,20,random_reader)!=NULL)

but you never created space to store the string read.


Apart from the algorithm used in your code, your program does not generate output because you are not closing your files. Add to the end of your main function the following lines:

fclose( outfile );
fclose( myfile );
fclose( randome_reader );

Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜