/*
Class:        cs312
  Lab:          5b
  Description:  Counts frequencies of words using a hash table
 */
import java.util.Hashtable; 
import java.util.StringTokenizer;
import java.util.Enumeration;
				/* An object that implements the Enumeration interface 
                          * generates a series of elements, one at a time. 
                          * Successive calls to the nextElement method return 
                              * successive elements of the series. */
import java.io.FileReader;
import java.io.BufferedReader;
public class CountWords1 {
    public static void main( String args[] ){
	if( args.length > 0 ){
	    try{
		/* Open file */
		BufferedReader in = new BufferedReader( new FileReader(args[0]) );
		Hashtable count = new Hashtable(500);
		String inLine = null;
		while( (inLine = in.readLine()) != null ){
			StringTokenizer words = new StringTokenizer
( inLine, " - . , ' : ; ? ! @ < > # $ % ^ & * ( ) + = / 1 2 3 4 5 6 7 8 9 0 " );
		    while( words.hasMoreTokens() ){
			Object w = words.nextToken().toLowerCase();
			/* Seen the word before? Incrememnt counter */
			if( count.containsKey(w) )  // the function containsKey();
                                              // Test whether the specified key 
                                              //has an associated value
                                              // in the table.
                        {
			    Integer c = (Integer)(count.get(w)); 
			    count.put( w, new Integer( c.intValue() + 1 ));
			}
			else{
                        // The function put(); is from Hashtable.java 
                        // Associate the specified value with the specified key.
                        // Precondition:  The key is not null.
			    count.put( w, new Integer(1) );
			}
		    }
		}
		in.close();
		/* Display result */
		System.out.println("Word	Freq" );
		System.out.println("------	----- ");
		Enumeration words = count.keys();
            /* The function hasMoreElements(); is from util.Enumeration;
               Tests if this enumeration 
               contains more elements return true if and only if this 
               enumeration object contains at least one more element to provide;
               false otherwise.
            */
		while( words.hasMoreElements() )
                {   /**
                * The function nextElement(); Returns the next element of 
                * this enumeration if this enumeration object has at
                * least one more element to provide. return the
                * next element of this enumeration.   exception
                * NoSuchElementException  if no more elements exist.
                */
		    Object w = words.nextElement(); 
                    // The function get() is from util.Hashtable.java 
                    // Retrieve the value associated with the specified key
                    // in the table, if there is any.  If not, the value
                    // null will be returned.
		    System.out.println(count.get(w)+ "	" + w  );
		}
	    }
	    catch( Exception e ){
		System.err.println(e);
		System.exit(-1);
	    }
	}
	else{
	    System.err.println( "Usage: java CountWords filename\n" );
	    System.exit(-1);
	}
    }
}
/*    OUTPUT FOR SAMPLE 1
Z:\lab5>javac Enumeration.java
Z:\lab5>java CountWords1 sample1.txt 
Word    Freq
------  -----
2       object
1       teaches
1       using
2       java
1       and
1       rigorous
1       makes
2       oriented
1       approach
1       informal
1       includes
Word    Freq
------  -----
1       it
2       structures
1       of
1       use
1       constr
1       with
1       concepts
1       yet
1       classic
1       an
3       the
2       appropriate
2       data
*/
/*    OUTPUT FOR SAMPLE 2
Z:\lab5>java CountWords1 sample2.txt
Word    Freq
------  -----
1       relates
1       support
1       mandates
1       tech
1       throughout
2       three
1       related
1       feel
1       was
3       oals
1       privacy
1       always
1       memory
1       took
2       rules
1       assistance
1       into
1       added
1       workstations
6       links
*/
/*__________________________*/
public interface Enumeration {
    /**
     * Tests if this enumeration contains more elements.
     *
     * return true if and only if this enumeration object
     *           contains at least one more element to provide;
     *          false otherwise.
     */
    boolean hasMoreElements();
    /**
     * Returns the next element of this enumeration if this enumeration
     * object has at least one more element to provide.
     *
     * @return     the next element of this enumeration.
     * @exception  NoSuchElementException  if no more elements exist.
     */
    Object nextElement();
}