HuffmanCode.java

 avatar
unknown
plain_text
2 years ago
3.9 kB
17
Indexable
import java.util.*;
import java.io.*;

public class HuffmanCode {
    private HuffmanNode head;
    public HuffmanCode(int[] frequencies){
        Queue<HuffmanNode> Pqueue = new PriorityQueue<HuffmanNode>();
        for (int i = 0; i < frequencies.length; i++){
            if (frequencies[i] > 0){
                Pqueue.add(new HuffmanNode(i, frequencies[i]));
            }
        }

        while(Pqueue.size() > 1){
            //HuffmanNode firstRemove = Pqueue.peek();
            HuffmanNode firstRemove = Pqueue.remove();
            // HuffmanNode secondRemove = Pqueue.peek();
            HuffmanNode secondRemove = Pqueue.remove();
            Pqueue.add(new HuffmanNode(-1, firstRemove.frequency + secondRemove.frequency , firstRemove, secondRemove));
        }
        head = Pqueue.remove();
    }
    public HuffmanCode(Scanner input){
        while (input.hasNextLine()){
            String data = input.nextLine();
            String encoding = input.nextLine();
            head = maketree(head, Integer.parseInt(data), encoding);
        }
    }
    private HuffmanNode maketree(HuffmanNode current, int data, String encoding){
        if (encoding.length() == 0){
            return new HuffmanNode(data, 0, null, null);
        }
        else{
            if (current == null){
                current = new HuffmanNode(-1, 0, null, null);
            }
            if (encoding.charAt(0) == '0'){
                current.left = maketree(current.left, data, encoding.substring(1));   
            }
            else{
                current.right = maketree(current.right, data, encoding.substring(1));
            }
            return current;
        }
    }
    public void save(PrintStream output){
        String continuing = "";
        traverseTree(output, head, continuing);
    }

    //Note: Let the user know the tree-reading order in the comment.
    private void traverseTree(PrintStream output, HuffmanNode curr, String continuing){
        if (curr != null){
            if (curr.left == null && curr.right == null){
                output.println(curr.getASCII());
                output.println(continuing);
            }
            else{
                if (curr.left != null){
                    traverseTree(output, curr.left, continuing + "0");
                }
                if (curr.right != null){
                    traverseTree(output, curr.right, continuing + "1");
                }
            }
        }
    }
    public void translate(BitInputStream input, PrintStream output){
        //public int nextBit()
        while(input.hasNextBit()){
            translate(input, output, head);
        }
    }
    private void translate (BitInputStream input, PrintStream output, HuffmanNode curr){
        if (curr.left == null && curr.right == null){
            output.write((char)curr.getASCII());
        }
        else{
            int nextBit = input.nextBit();
            if (nextBit == 0){
                translate(input, output, curr.left);
            }
            else{
                translate(input, output, curr.right);      
            }
    }
    }
    public static class HuffmanNode implements Comparable<HuffmanNode>{
        private int ASCIINo;
        private int frequency;
        private HuffmanNode left;
        private HuffmanNode right;

        public HuffmanNode(int ASCIINo, int frequency){
            this(ASCIINo, frequency, null, null);
        }

        public HuffmanNode(int ASCIINo, int frequency, HuffmanNode left, HuffmanNode right){
            this.ASCIINo = ASCIINo;
            this.frequency = frequency;
            this.left = left;
            this.right = right;
        }
        public int getASCII(){
            return this.ASCIINo;
        }
        
        @Override
        public int compareTo(HuffmanNode other){
            return this.frequency - other.frequency; 
        }
    }
    
}