title: Explain markov-chain algorithm in layman's terms
body: <p>I don't quite understand this Markov... it takes two words a prefix and suffix saves up a list of them and makes random word?</p>
  
  <pre><code>    /* Copyright (C) 1999 Lucent Technologies */
  /* Excerpted from 'The Practice of Programming' */
  /* by Brian W. Kernighan and Rob Pike */
  
  #include &lt;time.h&gt;
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;deque&gt;
  #include &lt;map&gt;
  #include &lt;vector&gt;
  
  using namespace std;
  
  const int  NPREF = 2;
  const char NONWORD[] = "\n";    // cannot appear as real line: we remove newlines
  const int  MAXGEN = 10000; // maximum words generated
  
  typedef deque&lt;string&gt; Prefix;
  
  map&lt;Prefix, vector&lt;string&gt; &gt; statetab; // prefix -&gt; suffixes
  
  void        build(Prefix&amp;, istream&amp;);
  void        generate(int nwords);
  void        add(Prefix&amp;, const string&amp;);
  
  // markov main: markov-chain random text generation
  int main(void)
  {
      int nwords = MAXGEN;
      Prefix prefix;  // current input prefix
  
      srand(time(NULL));
      for (int i = 0; i &lt; NPREF; i++)
          add(prefix, NONWORD);
      build(prefix, cin);
      add(prefix, NONWORD);
      generate(nwords);
      return 0;
  }
  
  // build: read input words, build state table
  void build(Prefix&amp; prefix, istream&amp; in)
  {
      string buf;
  
      while (in &gt;&gt; buf)
          add(prefix, buf);
  }
  
  // add: add word to suffix deque, update prefix
  void add(Prefix&amp; prefix, const string&amp; s)
  {
      if (prefix.size() == NPREF) {
          statetab[prefix].push_back(s);
          prefix.pop_front();
      }
      prefix.push_back(s);
  }
  
  // generate: produce output, one word per line
  void generate(int nwords)
  {
      Prefix prefix;
      int i;
  
      for (i = 0; i &lt; NPREF; i++)
          add(prefix, NONWORD);
      for (i = 0; i &lt; nwords; i++) {
          vector&lt;string&gt;&amp; suf = statetab[prefix];
          const string&amp; w = suf[rand() % suf.size()];
          if (w == NONWORD)
              break;
          cout &lt;&lt; w &lt;&lt; "\n";
          prefix.pop_front(); // advance
          prefix.push_back(w);
      }
  }
  </code></pre>