/** * Reads characters on stdin and prints javacode for coding and decoding * the characters through a Huffman tree. * Only rough java statements are printed. * * (C) 2000 Johan Wahlin, johan@wahlin.nu * * Permission is hereby granted to use this code however you see fit. * The use of this code is on you own risk. No liability is accepted. */ import java.io.*; import java.util.*; class Node implements Comparable { Node left = null; Node right = null; int weight; int ch; Node( int w, int c ) { weight = w; ch = c; } Node( int w, int c, Node l, Node r ) { weight = w; ch = c; left = l; right = r; } public int compareTo( Object o ) { int retVal; Node n = (Node) o; retVal = weight - n.weight; // Equality is trickier if ( retVal == 0 ) if ( this == n ) retVal = 0; else retVal = -1; return retVal; } } class CreateTree { static String prePadZ( String in, int len ) { int leng = in.length(); StringBuffer zs = new StringBuffer(); for ( int i=0; i < len - leng; i++ ) zs.append( "0" ); return zs.append( in ).toString(); } static void printCase( Node n, String bits ) { if ( n == null ) { return; } else if ( n.ch != -1 ) { System.out.println( "case '" + (char) n.ch + "'" + " /*" + prePadZ( String.valueOf( n.weight ), 4 ) + "*/: " + "buf.append( \"" + bits + "\" );" + " break;" ); } else { printCase( n.left, bits + "0" ); printCase( n.right, bits + "1" ); } } static String printJava( Node n ) { if ( n == null ) { return ""; } else if ( n.ch != -1 ) { return "new Node( " + n.weight + ", " + n.ch + " )"; } else { return "new Node( " + n.weight + ", " + n.ch + ", " + printJava( n.left ) + ", " + printJava( n.right ) + " )"; } } public static void main( String [] args ) throws java.io.FileNotFoundException, java.io.IOException { int [] wc = new int[256]; int ch, i; TreeSet heap = new TreeSet(); Iterator iter; Node tree; ch = System.in.read(); while ( ch != -1 ) { wc[ch]++; ch = System.in.read(); } System.err.println( "Characters counted." ); for ( i=0; i < wc.length; i++ ) if ( wc[i] > 0 ) heap.add( new Node( wc[i], i ) ); System.err.println( heap.size() + " nodes created." ); while ( heap.size() > 1 ) { Node node, first, second; iter = heap.iterator(); // Get the nodes with the lowest weights first = (Node) iter.next(); second = (Node) iter.next(); // .. combine the two and add it heap.add( new Node( first.weight + second.weight, -1, first, second ) ); // .. and remove to two that made the combination heap.remove( (Object) first ); heap.remove( (Object) second ); } tree = (Node) heap.first(); heap = null; System.err.println( "Tree built." ); System.out.println( "StringBuffer buf = new StringBuffer();" ); System.out.println( "switch ( ch ) {" ); printCase( tree, "" ); System.out.println( "}" ); System.err.println( "Tree printed in Case form." ); System.out.println( "\n\n// Please insert Node definition from " + "CreateTree.java" ); System.out.println( printJava( tree ) ); System.err.println( "Tree printed in Java form." ); } }