亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

如何用Java實現啥夫曼編碼

2019-11-26 16:01:08
字體:
來源:轉載
供稿:網友

大家可能會想,程序和第三方提供了很多壓縮方式,何必自己寫壓縮代碼呢?不錯,如GZIP這樣的壓縮工具很多,可是在某些情況下(如文本內容小且字符不重復),GZIP壓縮后會比原始文本還要大。所以在某些特殊情況下用自己的壓縮方式可以更優。

大家可能早已忘記了在學校學習的哈夫曼知識,可以先在百度百科了解一下哈夫曼知識:http://baike.baidu.com/view/127820.htm

哈夫曼思想:統計文本字符重復率,求出各字符權值,再構造出一顆最優二叉樹(又稱哈夫曼樹),然后給每個葉子結點生成一個以位(bit)為單位的碼值,每個碼值不能做為其 他碼值的前綴,再將碼值合并以每8個生成一個字節。

復制代碼 代碼如下:

package com.huffman;

/**
 * 結點
 * @author Davee
 */
public class Node implements Comparable<Node> {
    int weight;//權值
    Node leftChild;//左孩子結點
    Node rightChild;//右孩子結點
    String huffCode;
    private boolean isLeaf;//是否是葉子
    Character value;

    public Node(Character value, int weight) {
        this.value = value;
        this.weight = weight;
        this.isLeaf = true;
    }

    public Node(int weight, Node leftChild, Node rightChild) {
        this.weight = weight;
        this.leftChild = leftChild;
        this.rightChild = rightChild;
    }

    public void increaseWeight(int i) {
        weight += i;
    }

    public boolean isLeaf() {
        return isLeaf;
    }

    @Override
    public int compareTo(Node o) {
        return this.weight - o.weight;
    }
}


復制代碼 代碼如下:

package com.huffman;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class HuffmanTree {
    private boolean debug = false;

    private HashMap<Character, Node> nodeMap;
    private ArrayList<Node> nodeList;

    public HuffmanTree() {
        nodeMap = new HashMap<Character, Node>();
        nodeList = new ArrayList<Node>();
    }

    public void setDebug(boolean debug) {
        this.debug = debug;
    }

    public String decode(Map<String, Character> codeTable, String binary) {
        int begin = 0, end = 1, count = binary.length();
        StringBuffer sb = new StringBuffer();
        while (end <= count) {
            String key = binary.substring(begin, end);
            if (codeTable.containsKey(key)) {
                sb.append(codeTable.get(key));
                begin = end;
            } else {
            }
            end++;
        }
        return sb.toString();
    }

    public String encode(String originText) {
        if (originText == null) return null;

        calculateWeight(originText);

//        if (debug) printNodes(nodeList);

        Node root = generateHuffmanTree(nodeList);

        generateHuffmanCode(root, "");

        if (debug) printNodes(root);

        StringBuffer sb = new StringBuffer();
        for (Character key : originText.toCharArray()) {
            sb.append(nodeMap.get(key).huffCode);
        }
        if (debug) System.out.println("二進制:"+sb.toString());

        return sb.toString();
    }

    /**
     * 計算葉子權值
     * @param text
     */
    private void calculateWeight(String text) {
        for (Character c : text.toCharArray()) {
            if (nodeMap.containsKey(c)) {
                nodeMap.get(c).increaseWeight(1);//權值加1
            } else {
                Node leafNode = new Node(c, 1);
                nodeList.add(leafNode);
                nodeMap.put(c, leafNode);
            }
        }
    }

    /**
     * 生成哈夫曼樹
     * @param nodes
     */
    private Node generateHuffmanTree(ArrayList<Node> nodes) {
        Collections.sort(nodes);
        while(nodes.size() > 1) {
            Node ln = nodes.remove(0);
            Node rn = nodes.remove(0);
            insertSort(nodes, new Node(ln.weight + rn.weight, ln, rn));
        }
        Node root = nodes.remove(0);
        nodes = null;
        return root;
    }

    /**
     * 插入排序
     * @param sortedNodes
     * @param node
     */
    private void insertSort(ArrayList<Node> sortedNodes, Node node) {
        if (sortedNodes == null) return;

        int weight = node.weight;
        int min = 0, max = sortedNodes.size();
        int index;
        if (sortedNodes.size() == 0) {
            index = 0;
        } else if (weight < sortedNodes.get(min).weight) {
            index = min;//插入到第一個
        } else if (weight >= sortedNodes.get(max-1).weight) {
            index = max;//插入到最后
        } else {
            index = max/2;
            for (int i=0, count=max/2; i<=count; i++) {
                if (weight >= sortedNodes.get(index-1).weight && weight < sortedNodes.get(index).weight) {
                    break;
                } else if (weight < sortedNodes.get(index).weight) {
                    max = index;
                } else {
                    min = index;
                }
                index = (max + min)/2;
            }
        }
        sortedNodes.add(index, node);
    }

    private void generateHuffmanCode(Node node, String code) {
        if (node.isLeaf()) node.huffCode = code;
        else {
            generateHuffmanCode(node.leftChild, code + "0");
            generateHuffmanCode(node.rightChild, code + "1");
        }
    }

    /**
     * 生成碼表
     * @return
     */
    public Map<String, Character> getCodeTable() {
        Map<String, Character> map = new HashMap<String, Character>();
        for (Node node : nodeMap.values()) {
            map.put(node.huffCode, node.value);
        }
        return map;
    }

    /**
     * 打印節點信息
     * @param root
     */
    private void printNodes(Node root) {
        System.out.println("字符  權值  哈夫碼");
        printTree(root);
    }

    private void printTree(Node root) {
        if (root.isLeaf()) System.out.println((root.value == null ? "   " : root.value)+"    "+root.weight+"    "+(root.huffCode == null ? "" : root.huffCode));
        if (root.leftChild != null) printTree(root.leftChild);
        if (root.rightChild != null) printTree(root.rightChild);
    }

    /**
     * 打印節點信息
     * @param nodes
     */
    private void printNodes(ArrayList<Node> nodes) {
        System.out.println("字符  權值  哈夫碼");
        for (Node node : nodes) {
            System.out.println(node.value+"    "+node.weight+"    "+node.huffCode);
        }
    }
}


復制代碼 代碼如下:

package com.test;

import java.util.Map;

import com.huffman.HuffUtils;
import com.huffman.HuffmanTree;

public class Test {
    public static void main(String[] args) {
        String originText = "abcdacaha";
        HuffmanTree huffmanTree = new HuffmanTree();
        huffmanTree.setDebug(true);//測試
        String binary = huffmanTree.encode(originText);
        byte[] bytes = HuffUtils.binary2Bytes(binary);
        Map<String, Character> codeTable = huffmanTree.getCodeTable();
        int lastByteNum = binary.length() % 8;
        System.out.println(bytes.length);
        //將bytes、codeTable、 lastByteNum傳遞到服務器端
        //省略。。。。。。

        /*
                         服務器端解析
                         接收到參數,并轉換成bytes、relationMap、 lastByteNum
        */
        String fullBinary = HuffUtils.bytes2Binary(bytes, lastByteNum);
        System.out.println("服務器二進制:"+fullBinary);
        String retrieveText = huffmanTree.decode(codeTable, fullBinary);
        System.out.println("恢復文本:"+retrieveText);
    }
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品自拍视频在线观看| 美女久久久久久久| 深夜成人在线观看| 欧美亚洲国产另类| 美女视频黄免费的亚洲男人天堂| 亚洲欧美在线播放| 亚洲成人久久一区| 九九九热精品免费视频观看网站| 亚洲美女在线视频| 亚洲人av在线影院| 91精品国产成人www| 亚洲欧美国产另类| 色偷偷91综合久久噜噜| 亚洲电影免费观看高清完整版在线观看| 韩日精品中文字幕| 日韩av免费看| 亚洲网站在线看| 欧美日韩福利电影| 国产精品xxxxx| xxxx欧美18另类的高清| 日韩精品视频在线观看网址| 国产精品欧美在线| 亚洲第一av在线| 国产99久久精品一区二区 夜夜躁日日躁| 国产精品成人观看视频国产奇米| 精品视频在线播放| 欧美一区二区三区免费视| 精品毛片网大全| 欧美激情va永久在线播放| 亚洲第一区中文字幕| 国产精品久久久久久久美男| 精品成人av一区| 亚洲国产天堂久久综合| 久久久人成影片一区二区三区观看| 欧美一级片一区| 国产成人精品一区二区在线| 国产精品第一视频| 中文字幕一精品亚洲无线一区| 欧美日韩高清区| 国产精品99蜜臀久久不卡二区| 国产精品视频久| 国产成人精品久久二区二区| 国产精品久久久久久久久男| 97色在线视频观看| 国产成人精品久久久| 中文字幕少妇一区二区三区| 日韩精品免费在线视频观看| 欧美日韩在线另类| 国产97在线观看| 国产一区二区三区在线免费观看| 69**夜色精品国产69乱| 亚洲欧美日本精品| 国产精品久久久久久久午夜| 色七七影院综合| 亚洲a∨日韩av高清在线观看| 国产亚洲欧美日韩一区二区| 国产日韩在线亚洲字幕中文| 亚洲精品免费一区二区三区| 精品福利在线看| 亚洲欧美国产精品专区久久| 日韩在线视频一区| 亚洲人成电影在线播放| 久久69精品久久久久久久电影好| 精品福利樱桃av导航| 精品久久久一区| 在线观看国产精品91| 日韩a**站在线观看| 久久理论片午夜琪琪电影网| 欧美成人午夜免费视在线看片| 最近2019中文字幕一页二页| 色妞色视频一区二区三区四区| 麻豆乱码国产一区二区三区| 久久亚洲精品中文字幕冲田杏梨| 国产亚洲欧美aaaa| 欧美第一黄色网| 欧洲成人免费视频| 国产精品露脸av在线| 亚洲最大成人网色| 国产精品尤物福利片在线观看| 国产精品视频地址| 欧美肥老妇视频| 欧美在线视频网| 成人免费看片视频| 欧美情侣性视频| 日韩成人中文电影| 亚洲欧美第一页| 最近免费中文字幕视频2019| 精品国产31久久久久久| 久久久久五月天| 美乳少妇欧美精品| www.亚洲免费视频| 精品动漫一区二区三区| 成人性生交大片免费看小说| 国产精品美女久久久久av超清| 久久久久久久久久av| 国产精品中文字幕在线| 欧美亚洲激情在线| 亚洲激情视频在线观看| wwwwwwww亚洲| 亚洲国产天堂网精品网站| 午夜精品一区二区三区在线视| 日韩在线观看高清| 日韩精品福利在线| 伦理中文字幕亚洲| 久久影视电视剧免费网站| 97在线免费视频| 97婷婷涩涩精品一区| 92版电视剧仙鹤神针在线观看| 欧美多人爱爱视频网站| 国产精品福利观看| 欧美电影在线观看| 国产精品久久久亚洲| 一本一本久久a久久精品牛牛影视| 精品久久久在线观看| 在线观看免费高清视频97| 国产成人精品亚洲精品| 亚洲人成伊人成综合网久久久| 久久久久久国产三级电影| 日韩av电影免费观看高清| 日本欧美爱爱爱| 91在线视频精品| 国产激情视频一区| 国产精品久久久久一区二区| 欧美午夜无遮挡| 成人写真福利网| 亚洲成人av片| 国内精品400部情侣激情| 国产69精品99久久久久久宅男| 91精品国产高清自在线看超| 欧美成人午夜激情视频| 日韩大陆欧美高清视频区| 亚洲成人国产精品| 日本亚洲欧美三级| 亚洲免费影视第一页| 国产日韩在线亚洲字幕中文| 成人在线免费观看视视频| 国产精品91视频| 国产国语videosex另类| 亚洲成人久久电影| 欧美性极品xxxx娇小| 亚洲精品中文字| 欧美性猛交xxxx乱大交3| 亚洲国内精品在线| 九九热这里只有精品6| 高潮白浆女日韩av免费看| 欧美丰满老妇厨房牲生活| 性欧美亚洲xxxx乳在线观看| 免费av一区二区| 91探花福利精品国产自产在线| 精品国产91久久久久久老师| 91精品久久久久久综合乱菊| 亚洲福利影片在线| 欧美老女人bb| 国产精品免费观看在线| 亚洲va久久久噜噜噜久久天堂| 国产原创欧美精品| 国产成人综合av| 日韩av在线导航| 亚洲999一在线观看www| 国产成人精品一区二区在线| 国产精品入口免费视| 国产这里只有精品| 欧美视频一二三| 亚洲美女视频网|