package huffman; import java.util.ArrayList; /** * This class is designed to test each step of the huffman coding process when run */ public class Driver { public static void main(String[] args) { String[] methods = { "makeSortedList", "makeTree", "makeEncodings", "encodeFromArray", "decode" }; String[] options = { "Test new file", "Test new method on the same file", "Quit" }; int repeatChoice = 0; do { System.err.print("Enter an input text file name => "); String input = StdIn.readLine(); System.err.println(); do { System.err.println("What method would you like to test?"); for (int i = 0; i < 5; i++) System.err.printf("%d. %s\n", i + 1, methods[i]); System.err.print("Enter a number => "); int choice = StdIn.readInt(); StdIn.readLine(); System.err.println(); switch (choice) { case 1: testSortedList(input); break; case 2: testMakeTree(input); break; case 3: testMakeEncodings(input); break; case 4: testEncode(input); break; case 5: testDecode(input); break; default: System.err.println("Not a valid method to test!"); } StdIn.resync(); System.err.println("\nWhat would you like to do now?"); for (int i = 0; i < 3; i++) System.err.printf("%d. %s\n", i + 1, options[i]); System.err.print("Enter a number => "); repeatChoice = StdIn.readInt(); StdIn.readLine(); System.err.println(); } while (repeatChoice == 2); } while (repeatChoice == 1); } private static void testSortedList(String input) { // Call sorted list method, and output all of them comma separated ArrayList sortedList = HuffmanCoding.makeSortedList(input); StdOut.println("Note that the decimals are rounded to 2 decimal places.\n"); StdOut.printf("%s->%.2f", charToString(sortedList.get(0).getCharacter()), sortedList.get(0).getProbOccurrence()); for (int i = 1; i < sortedList.size(); i++) { char c = sortedList.get(i).getCharacter(); StdOut.printf(", %s->%.2f", charToString(c), sortedList.get(i).getProbOccurrence()); } StdOut.println(); } private static String charToString(char c) { // Make sure special characters don't actually print themselves out switch (c) { case '\n': return "\\n"; case '\t': return "\\t"; case '\r': return "\\r"; default: return "" + c; } } private static void testMakeTree(String input) { // Call list method and tree method, printing out the tree ArrayList sortedList = HuffmanCoding.makeSortedList(input); StdOut.println("Note that the decimals are rounded to 2 decimal places\n"); printTree(HuffmanCoding.makeTree(sortedList)); StdOut.println(); } private static void printTree(TreeNode root) { printTree(root, "", false, true); } private static void printTree(TreeNode n, String indent, boolean isRight, boolean isRoot) { StdOut.print(indent); // Print out either a right connection or a left connection if (!isRoot) StdOut.print(isRight ? "|-1- " : "+-0- "); // If we're at the root, we don't want a 1 or 0 else StdOut.print("+--- "); if (n == null) { StdOut.println("null"); return; } // If we have an associated character print it too, otherwise just the probability if (n.getData().getCharacter() != null) StdOut.print(charToString(n.getData().getCharacter()) + "->"); StdOut.printf("%.2f ", n.getData().getProbOccurrence()); StdOut.println(); // If no more children we're done if (n.getLeft() == null && n.getRight() == null) return; // Add to the indent based on whether we're branching left or right indent += isRight ? "| " : " "; printTree(n.getRight(), indent, true, false); printTree(n.getLeft(), indent, false, false); } private static void testMakeEncodings(String input) { // Call list, tree, and encoding methods ArrayList sortedList = HuffmanCoding.makeSortedList(input); TreeNode huffmanTree = HuffmanCoding.makeTree(sortedList); String[] encodings = HuffmanCoding.makeEncodings(huffmanTree); boolean first = true; // Print out all encodings (which are not null) for (int i = 0; i < 128; i++) { if (encodings[i] != null) { if (!first) StdOut.print(", "); StdOut.printf("%s->%s", charToString((char) i), encodings[i]); first = false; } } StdOut.println(); } private static void testEncode(String input) { // Take in an encoding file and call encode method System.err.print("File to encode into (can be new) => "); String encodedFile = StdIn.readLine(); System.err.println(); ArrayList sortedList = HuffmanCoding.makeSortedList(input); TreeNode huffmanTree = HuffmanCoding.makeTree(sortedList); String[] encodings = HuffmanCoding.makeEncodings(huffmanTree); HuffmanCoding.encodeFromArray(encodings, input, encodedFile); System.err.println("The input text file has been encoded into " + encodedFile); } private static void testDecode(String input) { // Encode and decode the file (with decode method) // Can be piped to a file for large inputs System.err.print("File to encode into (can be new) => "); String encodedFile = StdIn.readLine(); System.err.println(); ArrayList sortedList = HuffmanCoding.makeSortedList(input); TreeNode huffmanTree = HuffmanCoding.makeTree(sortedList); String[] encodings = HuffmanCoding.makeEncodings(huffmanTree); HuffmanCoding.encodeFromArray(encodings, input, encodedFile); StdIn.resync(); System.err.println("The input text file has been encoded into " + encodedFile); System.err.print("File to decode into (can be new) => "); String decodedFile = StdIn.readLine(); System.err.println(); HuffmanCoding.decode(encodedFile, huffmanTree, decodedFile); System.err.println("The file has been decoded into " + decodedFile); System.err.println(); } }