priority queue - java huffman tree precedence -
i have 2 questions following code have been researching on past couple of days. how can implement following rules if there multiple ties (meaning same number of frequencies) give single letter groups precedence on multiple letters , alphabetically? second question is, point me in write direction regards code encode/decode? should implement through main statement or go ahead , write new class? little stuck on start.
import java.util.*; //the following code hardcoded 2 separate arrays consisting of //characters , corresponding frequency. application takes in these 2 //arrays , constructs huffman encoding tree. begins showing user //letters, frequency, , huffman code assigned letter. //the application takes in .txt file various strings , encodes them. //this result shown. [still working on part-- question above] abstract class huffmantree implements comparable<huffmantree> { public final int frequency; // frequency of tree public huffmantree(int freq) { frequency = freq; } // compares on frequency public int compareto(huffmantree tree) { return frequency - tree.frequency; } } class huffmanleaf extends huffmantree { public final char value; // character leaf represents public huffmanleaf(int freq, char val) { super(freq); value = val; } } class huffmannode extends huffmantree { public final huffmantree left, right; // subtrees public huffmannode(huffmantree l, huffmantree r) { super(l.frequency + r.frequency); left = l; right = r; } } public class huffman { public static void main(string[] args) { //symbols given hard code string letters = "abcdefghijklmnopqrstuvwxyz"; //converting string character array char[] letterarray = letters.tochararray(); //frequency of letters given above: int[] letterfreqs = {19, 16, 17, 11, 42, 12, 14, 17, 16, 5, 10, 20, 19, 24, 18, 13, 1, 25, 35, 25, 15, 5, 21, 2, 8, 3}; // build tree huffmantree tree = constructtree(letterfreqs,letterarray); // print out results system.out.println("letter\tfrequency\tencoding"); printcodes(tree, new stringbuffer()); } // input array of frequencies , string of letters public static huffmantree constructtree(int[] charfreqs, char[] letters) { //sets priority queue begin constructing tree priorityqueue<huffmantree> trees = new priorityqueue<huffmantree>(); //for loop take in characters , there frequencies (int = 0; < charfreqs.length; i++) if (charfreqs[i] > 0) trees.offer(new huffmanleaf(charfreqs[i], letters[i])); assert trees.size() > 0; // loop until there 1 tree left while (trees.size() > 1) { // find 2 lowest frequencies huffmantree = trees.poll(); huffmantree b = trees.poll(); // construct new node , re-insert queue trees.offer(new huffmannode(a, b)); } return trees.poll(); } public static void printcodes(huffmantree tree, stringbuffer prefix) { assert tree != null; if (tree instanceof huffmanleaf) { huffmanleaf leaf = (huffmanleaf)tree; // print out character, frequency, , code leaf (which prefix) system.out.println(leaf.value + "\t" + leaf.frequency + "\t" + "\t" + prefix); } else if (tree instanceof huffmannode) { huffmannode node = (huffmannode)tree; // traverse left prefix.append('0'); printcodes(node.left, prefix); prefix.deletecharat(prefix.length()-1); // traverse right prefix.append('1'); printcodes(node.right, prefix); prefix.deletecharat(prefix.length()-1); } } }
in response first question, control ordering in priority queue via implementation of compareto()
, i'd following:
abstract class huffmantree implements comparable<huffmantree> { public final int frequency; // frequency of tree public huffmantree(int freq) { frequency = freq; } @override public int compareto(huffmantree tree) { int comparison = frequency - tree.frequency; if (0 == comparison) { comparison = comparisontiebreaker(tree); } return comparison; } private int comparisontiebreaker(huffmantree tree) { int comparison = 0; if (this.size() == 1) { if (tree.size() == 1) { // alphabetical comparison between 2 single-character groups: character.compare(this.firstchar(), tree.firstchar()); } else { comparison = -1; // single < multiple } } else if (tree.size() == 1) { comparison = 1; // multiple > single } return comparison; } public abstract int size(); public abstract char firstchar(); }
as 2 abstract methods, in huffmanleaf
, size()
returns 1 , firstchar()
returns character. in huffmannode
, size()
returns left.size() + right.size()
(basic recursion) , firstchar()
can return left.firstchar()
, although firstchar()
never called on huffmannode
.
in response second question, think should have encode()
, decode()
methods, either in huffman
class or in class. can call them main, i'd pull out of main method re-used elsewhere.
edit: asked me elaborate. second question not clear, seems you're stuck on how proceed encoding , decoding. start adding huffmantree
methods tomapfordecoding()
, tomapforencoding()
, each of returns map (it's same map both methods keys , values inversed). these maps (to used in encode()
, decode()
methods) allow constant-time conversion between input symbol , (encoded or decoded) output symbol. implementation of these methods can quite similar you've done in printcodes()
. put encode()
, decode()
methods, don't blocked that. put them it's convenient , move them later if need to.
Comments
Post a Comment