Java 实现Huffman 编码算法详解编程语言

  
static class Tree { 
                private Node root; 
   
                public Node getRoot() { 
                        return root; 
                } 
   
                public void setRoot(Node root) { 
                        this.root = root; 
                } 
        } 
   
        static class Node implements Comparable { 
                private String chars = ""; 
                private int frequence = 0; 
                private Node parent; 
                private Node leftNode; 
                private Node rightNode; 
   
                @Override 
                public int compareTo(Node n) { 
                        return frequence - n.frequence; 
                } 
   
                public boolean isLeaf() { 
                        return chars.length() == 1; 
                } 
   
                public boolean isRoot() { 
                        return parent == null; 
                } 
   
                public boolean isLeftChild() { 
                        return parent != null && this == parent.leftNode; 
                } 
   
                public int getFrequence() { 
                        return frequence; 
                } 
   
                public void setFrequence(int frequence) { 
                        this.frequence = frequence; 
                } 
   
                public String getChars() { 
                        return chars; 
                } 
   
                public void setChars(String chars) { 
                        this.chars = chars; 
                } 
   
                public Node getParent() { 
                        return parent; 
                } 
   
                public void setParent(Node parent) { 
                        this.parent = parent; 
                } 
   
                public Node getLeftNode() { 
                        return leftNode; 
                } 
   
                public void setLeftNode(Node leftNode) { 
                        this.leftNode = leftNode; 
                } 
   
                public Node getRightNode() { 
                        return rightNode; 
                } 
   
                public void setRightNode(Node rightNode) { 
                        this.rightNode = rightNode; 
                } 
        } 
   
   
统计方法实现如下: 
public static Map<Character, Integer> statistics(char[] charArray) { 
                Map<Character, Integer> map = new HashMap<Character, Integer>(); 
                for (char c : charArray) { 
                        Character character = new Character(c); 
                        if (map.containsKey(character)) { 
                                map.put(character, map.get(character) + 1); 
                        } else { 
                                map.put(character, 1); 
                        } 
                } 
   
                return map; 
        } 
   
   
构建树 
private static Tree buildTree(Map<Character, Integer> statistics, 
                        List leafs) { 
                Character[] keys = statistics.keySet().toArray(new Character[0]); 
   
                PriorityQueue priorityQueue = new PriorityQueue(); 
                for (Character character : keys) { 
                        Node node = new Node(); 
                        node.chars = character.toString(); 
                        node.frequence = statistics.get(character); 
                        priorityQueue.add(node); 
                        leafs.add(node); 
                } 
   
                int size = priorityQueue.size(); 
                for (int i = 1; i <= size - 1; i++) { 
                        Node node1 = priorityQueue.poll(); 
                        Node node2 = priorityQueue.poll(); 
   
                        Node sumNode = new Node(); 
                        sumNode.chars = node1.chars + node2.chars; 
                        sumNode.frequence = node1.frequence + node2.frequence; 
   
                        sumNode.leftNode = node1; 
                        sumNode.rightNode = node2; 
   
                        node1.parent = sumNode; 
                        node2.parent = sumNode; 
   
                        priorityQueue.add(sumNode); 
                } 
   
                Tree tree = new Tree(); 
                tree.root = priorityQueue.poll(); 
                return tree; 
        } 
   
   
   
编码 
public static String encode(String originalStr, 
                        Map<Character, Integer> statistics) { 
                if (originalStr == null || originalStr.equals("")) { 
                        return ""; 
                } 
   
                char[] charArray = originalStr.toCharArray(); 
                List leafNodes = new ArrayList(); 
                buildTree(statistics, leafNodes); 
                Map<Character, String> encodInfo = buildEncodingInfo(leafNodes); 
   
                StringBuffer buffer = new StringBuffer(); 
                for (char c : charArray) { 
                        Character character = new Character(c); 
                        buffer.append(encodInfo.get(character)); 
                } 
   
                return buffer.toString(); 
        } 
   
private static Map<Character, String> buildEncodingInfo(List leafNodes) { 
                Map<Character, String> codewords = new HashMap<Character, String>(); 
                for (Node leafNode : leafNodes) { 
                        Character character = new Character(leafNode.getChars().charAt(0)); 
                        String codeword = ""; 
                        Node currentNode = leafNode; 
   
                        do { 
                                if (currentNode.isLeftChild()) { 
                                        codeword = "0" + codeword; 
                                } else { 
                                        codeword = "1" + codeword; 
                                } 
   
                                currentNode = currentNode.parent; 
                        } while (currentNode.parent != null); 
   
                        codewords.put(character, codeword); 
                } 
   
                return codewords; 
        } 
   
解码 
public static String decode(String binaryStr, 
                        Map<Character, Integer> statistics) { 
                if (binaryStr == null || binaryStr.equals("")) { 
                        return ""; 
                } 
   
                char[] binaryCharArray = binaryStr.toCharArray(); 
                LinkedList binaryList = new LinkedList(); 
                int size = binaryCharArray.length; 
                for (int i = 0; i < size; i++) { 
                        binaryList.addLast(new Character(binaryCharArray[i])); 
                } 
   
                List leafNodes = new ArrayList(); 
                Tree tree = buildTree(statistics, leafNodes); 
   
                StringBuffer buffer = new StringBuffer(); 
   
                while (binaryList.size() > 0) { 
                        Node node = tree.root; 
   
                        do { 
                                Character c = binaryList.removeFirst(); 
                                if (c.charValue() == '0') { 
                                        node = node.leftNode; 
                                } else { 
                                        node = node.rightNode; 
                                } 
                        } while (!node.isLeaf()); 
   
                        buffer.append(node.chars); 
                } 
   
                return buffer.toString(); 
        } 
   
   
测试以及比较 
   
public static void main(String[] args) { 
                String oriStr = "Huffman codes compress data very effectively: savings of 20% to 90% are typical, " 
                                + "depending on the characteristics of the data being compressed. 中华崛起"; 
                Map<Character, Integer> statistics = statistics(oriStr.toCharArray()); 
                String encodedBinariStr = encode(oriStr, statistics); 
                String decodedStr = decode(encodedBinariStr, statistics); 
   
                System.out.println("Original sstring: " + oriStr); 
                System.out.println("Huffman encoed binary string: " + encodedBinariStr); 
                System.out.println("decoded string from binariy string: " + decodedStr); 
   
                System.out.println("binary string of UTF-8: " 
                                + getStringOfByte(oriStr, Charset.forName("UTF-8"))); 
                System.out.println("binary string of UTF-16: " 
                                + getStringOfByte(oriStr, Charset.forName("UTF-16"))); 
                System.out.println("binary string of US-ASCII: " 
                                + getStringOfByte(oriStr, Charset.forName("US-ASCII"))); 
                System.out.println("binary string of GB2312: " 
                                + getStringOfByte(oriStr, Charset.forName("GB2312"))); 
        } 
   
        public static String getStringOfByte(String str, Charset charset) { 
                if (str == null || str.equals("")) { 
                        return ""; 
                } 
   
                byte[] byteArray = str.getBytes(charset); 
                int size = byteArray.length; 
                StringBuffer buffer = new StringBuffer(); 
                for (int i = 0; i < size; i++) {                        byte temp = byteArray[i];                       buffer.append(getStringOfByte(temp));           }               return buffer.toString();       }       public static String getStringOfByte(byte b) {          StringBuffer buffer = new StringBuffer();               for (int i = 7; i >= 0; i--) { 
                        byte temp = (byte) ((b >> i) & 0x1); 
                        buffer.append(String.valueOf(temp)); 
                } 
   
                return buffer.toString(); 
        } 
  

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/10752.html

(0)
上一篇 2021年7月19日 10:28
下一篇 2021年7月19日 10:28

相关推荐

发表回复

登录后才能评论