I need a little help in understanding how to run this Markov Chain program (It's one of those Mark V Shaney type programs). The code itself is from The Practice of Programming by Keringhan and Pike. It's on Page 81 if anyone is particularly interested in cross-referencing. The way I understood their instructions, I should be able to produce the formatted version of the processed file by typing java Markov <goo.txt |fmt. However, when I do this the text remains unchanged. If I simply type java Markov <goo.txt without the extension it will jumble the text according to the Markov algorithm, but print it on a one word one line basis. It's probably a very simple thing I'm missing, but my understanding of how to run java programs from the terminal is still very basic. If anyone wants me to give examples of the file content and the output for different commands I will provide it, but I don't want this post to get too long, and I think it's more important to show the sample code below.


import java.io.IOException;
import java.io.InputStream;
import java.io.StreamTokenizer;
import java.util.Hashtable;
import java.util.Random;
import java.util.Vector;
 
 
public class Chain {
	static final int NPREF = 2; //size of prefix
	static final String NONWORD = "\n";
		//"word" that can't appear
	Hashtable statetab = new Hashtable();
		//key = Prefix, value = suffix Vector
	Prefix prefix = new Prefix(NPREF,NONWORD);
		//initial prefix
	Random rand = new Random();
 
	//Chain build: build State table from input stream
	void build (InputStream in )throws IOException{
		@SuppressWarnings("deprecation")
		StreamTokenizer st = new StreamTokenizer(in);
 
		st.resetSyntax();  //remove default rules
		st.wordChars(0,Character.MAX_VALUE); //turn on all chars
		st.whitespaceChars(0, ' ');
		while(st.nextToken()!= st.TT_EOF)
			add(st.sval);
		add(NONWORD);
	}
 
	//Chain add: add word to suffix list, update prefix
	void add(String word){
		Vector suf = (Vector) statetab.get(prefix);
		if(suf== null){
			suf = new Vector();
			statetab.put(new Prefix(prefix), suf);
		}
		suf.addElement(word);
		prefix.pref.removeElementAt(0);
		prefix.pref.addElement(word);
 
	}
 
	//Chain generate: generate output words
	void generate(int nwords){
		prefix = new Prefix(NPREF,NONWORD);
		for(int i =0;i<nwords;i++){
			Vector s = (Vector) statetab.get(prefix);
			int r = Math.abs(rand.nextInt())%s.size();String suf = (String) s.elementAt(r);
			if(suf.equals(NONWORD) )
				break;
			System.out.println(suf);
			prefix.pref.removeElementAt(0);
			prefix.pref.addElement(suf);
		}
	}
 
}

import java.util.Vector;
 
 
public class Prefix {
 
	static final int MULTIPLIER = 31;
 
	public Vector pref;
 
	//Prefix constructor: duplicate existing prefix
	Prefix (Prefix p){
		pref = (Vector) p.pref.clone();
	}
 
	//Prefix constructor: n copies of str
	Prefix (int n, String str){
		pref = new Vector();
		for(int i = 0;i<n; i++)
			pref.addElement(str);
	}
 
	//Prefix hashcode: generate hash from all prefi words
	public int hashCode(){
		int h = 0;
		for(int i =0; i<pref.size();i++)
			h = MULTIPLIER * h + pref.elementAt(i).hashCode();
			return h;
	}
 
	//Prefix equals: compare two prefixes for equal words
	public boolean equals(Object o){
		Prefix p = (Prefix)o;
		for(int i =0;i<pref.size();i++)
			if (!pref.elementAt(i).equals(p.pref.elementAt(i)))
				return false;
 
		return true;
	}
 
}

import java.io.IOException;
 
 
public class Markov {
	static final int MAXGEN = 1000;//maximum words generated
 
	public static void main (String [] args) throws IOException
	{
		Chain chain = new Chain();
		int nwords = MAXGEN;
 
		chain.build(System.in);
		chain.generate(nwords);
	}
 
}


--- Update ---

Actually, now that I've tried it again, both methods seem to be producing the words in the original order. Maybe something is wrong with the way I copied down the program?