日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

赫夫曼编码字节数组

發布時間:2023/12/3 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 赫夫曼编码字节数组 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

思路分析

代碼實現

package com.atguigu.huffmancode;import com.sun.org.glassfish.external.statistics.CountStatistic; import com.sun.org.glassfish.external.statistics.StringStatistic;import java.util.*;/*** @創建人 wdl* @創建時間 2021/3/27* @描述*/ public class HuffmanCode {public static void main(String[] args) {String content="i like like like java do you like a java";byte[] contentBytes = content.getBytes();System.out.println(contentBytes.length);//40List<Node> nodes = getNodes(contentBytes);System.out.println(nodes);//測試一把,創建的二叉樹System.out.println("赫夫曼樹");Node huffmanTreeRoot = createHuffmanTree(nodes);System.out.println("前序遍歷");huffmanTreeRoot.preOrder();//測試一把是否生成了對應的赫夫曼編碼Map<Byte, String> huffmanCodes = getCodes(huffmanTreeRoot);System.out.println("生成的赫夫曼編碼表"+huffmanCodes);//測試byte[] huffmanCodeBytes = zip(contentBytes, huffmanCodes);System.out.println(Arrays.toString(huffmanCodeBytes));//17}/**** @param bytes 這時原始的字符串對應的byte[]* @param huffmanCodes 生成的赫夫曼編碼map* @return 返回赫夫曼編碼表處理后的byte[]*///編寫一個方法,將字符串對應的byte[]數組,通過生成的赫夫曼編碼表,返回一個赫夫曼編碼壓縮有的byte[]private static byte[] zip(byte[] bytes,Map<Byte,String> huffmanCodes){//1.先利用huffmanCodes將bytes轉成赫夫曼編碼對應的字符串StringBuilder stringBuilder = new StringBuilder();//遍歷bytes數組for(byte b:bytes){stringBuilder.append(huffmanCodes.get(b));}System.out.println("測試stringBuilder="+stringBuilder.toString());//將1010111011 轉成byte數組//統計返回byte[] huffmanCodeBytes 長度//一句話 int len=(stringBuilder.length()+7)/8int len;if(stringBuilder.length()%8==0){len=stringBuilder.length()/8;}else {len=stringBuilder.length()/8+1;}//創建存儲壓縮有的byte[]byte[] huffmanCodeBytes=new byte[len];int index=0;//記錄是第幾個bytefor (int i = 0; i < stringBuilder.length(); i+=8) {//因為每8位對應一個byte,所以步長+8String strByte;if(i+8>stringBuilder.length()){//不夠8位strByte = stringBuilder.substring(i);}else {strByte = stringBuilder.substring(i, i + 8);}//將strByte轉成一個byte,放入到huffmanCodeByteshuffmanCodeBytes[index]= (byte) Integer.parseInt(strByte,2);index++;}return huffmanCodeBytes;}//生成赫夫曼樹對應的赫夫曼編碼//思路://1.將赫夫曼編碼表存放在Map<Byte,String>形式static Map<Byte,String> huffmanCodes= new HashMap<Byte,String>();// 32->01 97->100...//2.在生成赫夫曼編碼表示,需要去拼接璐姐,定義一個StringBuilder存儲某個葉子結點的路徑static StringBuilder stringBuilder=new StringBuilder();//這里為了調用方便,我們重載getCodesprivate static Map<Byte,String> getCodes(Node root){if(root==null){return null;}//處理root的左子樹getCodes(root.left,"0",stringBuilder);//處理root的右子樹getCodes(root.right,"1",stringBuilder);return huffmanCodes;}/*** 功能:將傳入的node節點的所有葉子節點的赫夫曼編碼的到,并放入到huffmanCodes集合* @param node 傳入節點* @param code 路徑:左子節點是0,右子節點是1* @param stringBuilder 是用于拼接路徑*/private static void getCodes(Node node,String code,StringBuilder stringBuilder){StringBuilder stringBuilder2 = new StringBuilder(stringBuilder);//將code加入到stringBuild2stringBuilder2.append(code);if(node!=null){//如果node==null不處理//判斷當前node是葉子結點還是非葉子節點if(node.data==null){//非葉子節點//遞歸處理//向左getCodes(node.left,"0",stringBuilder2);//向右getCodes(node.right,"1",stringBuilder2);}else {//說明是一個葉子結點//表示找到了某個葉子節點的最后huffmanCodes.put(node.data,stringBuilder2.toString());}}}//前序遍歷的方法private static void preOrder(Node root){if(root!=null){root.preOrder();}else {System.out.println("赫夫曼樹為空");}}/**** @param bytes 接收字節數組* @return 返回的就是List形式*/private static List<Node> getNodes(byte[] bytes){//1.創建一個ArrayListArrayList<Node> nodes = new ArrayList<>();//遍歷bytes 統計每一個byte出現的次數->map[key,value]HashMap<Byte, Integer> counts = new HashMap<>();for(byte b:bytes){Integer count=counts.get(b);if (count==null){//map中還沒有這個字符數據,第一次counts.put(b,1);}else {counts.put(b,count+1);}}//把每一個鍵值對轉成Node對象,并加入到nodes集合//遍歷mapfor(Map.Entry<Byte,Integer> entry:counts.entrySet()){nodes.add(new Node(entry.getKey(),entry.getValue()));}return nodes;}//可以通過List創建對應的赫夫曼樹private static Node createHuffmanTree(List<Node> nodes){while (nodes.size()>1){//排序,從小到大Collections.sort(nodes);//取出第一顆最小的二叉樹Node leftNode = nodes.get(0);//取出第二顆最小的二叉樹Node rightNode = nodes.get(1);//創建一顆新的二叉樹,它的根節點沒有data,只有權值Node parent=new Node(null,leftNode.weight+rightNode.weight);parent.left=leftNode;parent.right=rightNode;//將已經處理的兩顆二叉樹從nodes刪除nodes.remove(leftNode);nodes.remove(rightNode);//將新的二叉樹,加入到nodesnodes.add(parent);}//nodes最后的節點,就是哈夫曼樹的根節點return nodes.get(0);}}//創建Node,待數據和權值 class Node implements Comparable<Node>{Byte data;//存放數據(字符)本身,比如'a'=>97 ' '=>32int weight;//權值,表示字符出現的次數Node left;Node right;public Node(Byte data, int weight) {this.data = data;this.weight = weight;}@Overridepublic int compareTo(Node o) {//從小到大排序return this.weight-o.weight;}@Overridepublic String toString() {return "Node{" +"data=" + data +", weight=" + weight +'}';}//前序遍歷public void preOrder(){System.out.println(this);if(this.left!=null){this.left.preOrder();}if (this.right!=null){this.right.preOrder();}}}

總結

以上是生活随笔為你收集整理的赫夫曼编码字节数组的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。