摘要:在計(jì)算機(jī)信息處理中,哈夫曼編碼是一種一致性編碼法又稱(chēng)熵編碼法,用于數(shù)據(jù)的無(wú)損耗壓縮。構(gòu)造樹(shù)時(shí)間復(fù)雜度選擇兩個(gè)使用頻率較小字符在字符串中出現(xiàn)的次數(shù)的結(jié)點(diǎn)合并生成出一個(gè)樹(shù)循環(huán)創(chuàng)建哈夫曼樹(shù)數(shù)組函數(shù)刪除數(shù)組中的第一個(gè)元素,并返回被刪除元素的值。
小草主要博客:http://homeway.me/
演示網(wǎng)址:http://huffman.sinaapp.com/
源文件下載地址:http://xiaocao.u.qiniudn.com/work/huffman-2013-12-19.zip
????哈夫曼樹(shù)─即最優(yōu)二叉樹(shù),帶權(quán)路徑長(zhǎng)度最小的二叉樹(shù),經(jīng)常應(yīng)用于數(shù)據(jù)壓縮。 在計(jì)算機(jī)信息處理中,“哈夫曼編碼”是一種一致性編碼法(又稱(chēng)“熵編碼法”),用于數(shù)據(jù)的無(wú)損耗壓縮。
????簡(jiǎn)單的,就是靠權(quán)值排序,然后,轉(zhuǎn)碼,最優(yōu)保存。
保存譯碼:在服務(wù)器端保存源字符串,命名為:”Encording.txt”
保存編碼:在服務(wù)器端保存壓縮后壓縮碼,命名為:”Decording.txt”
保存哈夫曼樹(shù):在服務(wù)器端保存哈夫曼樹(shù)數(shù)組,命名為:”Huffman.txt”
瀏覽器本地保存:在本地緩存輸入歷史。并且實(shí)現(xiàn)自行選擇本地版本。
前臺(tái)表單提交頁(yè)面,后臺(tái)表單處理頁(yè)面,以及哈夫曼壓縮,解壓縮系統(tǒng)。包含兩個(gè)主文件:huffman.php和index.php(另外還包含style.css控制樣式,huffman.js保存緩存和控制交互。)
|--index.php(處理基本表單,數(shù)據(jù)保存)
|--huffman.php(壓縮,解壓縮)
|--style.css(控制樣式)
|--huffman.js(保存緩存和控制交互)
huffman.php
的結(jié)點(diǎn)合并生成出一個(gè)樹(shù) */ //循環(huán)創(chuàng)建哈夫曼樹(shù)數(shù)組 while ($item1 = each($array)) { $item2 = each($array); $this->creat_tree($item1,$item2,$array,$HuffmanArray); asort($array); } //array_shift() 函數(shù)刪除數(shù)組中的第一個(gè)元素,并返回被刪除元素的值。 $HuffmanArray=array_shift($HuffmanArray); $tab=null; $code_tab=$this->creat_tab($HuffmanArray,$tab); //壓縮&轉(zhuǎn)換整個(gè)字符串為二進(jìn)制表達(dá)式 $binary=null; for($i=0; $i<$len; $i++) $binary.=$tab[ord($str{$i})]; //轉(zhuǎn)化為壓縮后的字符串 $code=$this->encode_bin($binary); //靜態(tài)huffman編碼算法壓縮后需保留huffman樹(shù) return array("tree"=>$HuffmanArray,"len"=>strlen($binary),"code"=>$code); } /** * 解壓縮入口 * $huffman:解壓所使用的huffman樹(shù) * $str:被壓縮的字符 * $blen:壓縮前的位長(zhǎng)度 */ public function decode($huffman,$str,$blen) { $len=strlen($str); $binary=null; //將編碼解為二進(jìn)制表達(dá)式 for($i=0;$i<$len;$i++) $binary.=str_pad(base_convert(ord($str{$i}),10,2),8,"0",STR_PAD_LEFT); $binary=substr($binary,0,$blen); return $this->decode_tree($binary,$huffman,$huffman); } /** * 將壓縮后的二進(jìn)制表達(dá)式再轉(zhuǎn)為字符串 * $binary:二進(jìn)制表達(dá)式字串 */ private function encode_bin($binary) { $len=strlen($binary); //二進(jìn)制轉(zhuǎn)字符需要整8位,不足8位補(bǔ)0 $blen=$len+8-$len%8; $binary=str_pad($binary,$blen,"0"); $encode=null; //每8位轉(zhuǎn)為一個(gè)字符 for($i=7;$i<$blen;$i+=8) { $frag=substr($binary,$i-7,8); //base_convert() 函數(shù)在任意進(jìn)制之間轉(zhuǎn)換數(shù)字 $encode.=chr(base_convert($frag,2,10)); } return $encode; } /** * 構(gòu)造huffman樹(shù),使用貪婪算法選擇最小的兩個(gè)元素作為樹(shù)的子節(jié)點(diǎn) * $item1:權(quán)重最小的元素1 * $item2:權(quán)重次小的元素2 * $array:所有字符出現(xiàn)次數(shù)表<權(quán)重表> *$HuffmanArray:保存生成的huffman樹(shù)結(jié)構(gòu) */ private function creat_tree($item1,$item2,&$array,&$HuffmanArray) { list($key,$weight)=$item1; list($key2,$weight2)=$item2; //假設(shè)當(dāng)前樹(shù)的左右節(jié)點(diǎn)為空節(jié)點(diǎn) $c1=$key; $c2=$key2; //判斷兩個(gè)元素若為樹(shù)則直接作為節(jié)點(diǎn)并入主樹(shù) if(isset($HuffmanArray[$key2])) { $c2=$HuffmanArray[$key2]; unset($HuffmanArray[$key2]); } if(isset($HuffmanArray[$key])) { $c1=$HuffmanArray[$key]; unset($HuffmanArray[$key]); } //設(shè)置樹(shù)結(jié)點(diǎn)權(quán)值 $array[$key2]=$weight+$weight2; //合并節(jié)點(diǎn)后刪除元素 unset($array[$key]); //合并到huffman樹(shù)中 $HuffmanArray[$key2]=array(0=>$c1,1=>$c2); } /** * 廣度優(yōu)先遍歷樹(shù),得到所有原字符對(duì)應(yīng)的二進(jìn)制表達(dá)式<01010...> * $tree:已經(jīng)構(gòu)建好的huffman樹(shù) * $tab:編碼表,保存所有字符對(duì)應(yīng)的編碼 * $a0:左遍歷樹(shù)的路徑<11010...> * $a1:右遍歷樹(shù)的路徑 */ private function creat_tab($tree,&$tab,$a0=null,$a1=null) { if($tree==null) return; //遍歷左右子樹(shù) foreach($tree as $node=>$ctree) { if(is_array($ctree)) { //判斷未到達(dá)葉子節(jié)點(diǎn)時(shí)再向下遍歷 $this->creat_tab($ctree,$tab,$a0.$node,$a1.$node); }else{ //遍歷到葉子節(jié)點(diǎn)<原字符ascii碼>時(shí)的所有路徑,既二進(jìn)制表達(dá)式,下同 $tab[$ctree]=${"a".$node}.$node; } } } /** * 使用進(jìn)制表達(dá)式深度優(yōu)先遍歷樹(shù),0為左子樹(shù),1為右子樹(shù),而到根節(jié)點(diǎn),即為二進(jìn)制表達(dá)式所指向的原字符 * $binary:二進(jìn)制表達(dá)式字串 * $huffman:huffman樹(shù) * $tree:當(dāng)前所遍歷的子樹(shù) * $i:指向二進(jìn)制表達(dá)式字串的<指針> * $code:解碼后的字符串 */ private function decode_tree($binary,$huffman,$tree,$i=0,$code=null) { $lr=$binary{$i}; //遍歷完成 if($lr==null) return $code; //判斷是否到根節(jié)點(diǎn),根節(jié)點(diǎn)既為二進(jìn)制表達(dá)式對(duì)應(yīng)的原字符ascii碼 if(is_array($tree[$lr])) { //繼續(xù)向下遍歷子樹(shù) return $this->decode_tree($binary,$huffman,$tree[$lr],$i+1,$code); }else{ //將二進(jìn)制表達(dá)式解碼為原字符 $code.=chr($tree[$lr]); return $this->decode_tree($binary,$huffman,$huffman,$i+1,$code); } } } ?>
下面是huffman.js本地緩存源碼
$( document ).ready(function(){ /*函數(shù)寫(xiě)的比較亂,慢慢改進(jìn)*/ //flag是用來(lái)判斷,是否需要添加緩存計(jì)數(shù) var flag=true; function get_Storage(key){ return window.localStorage.getItem(key); } function set_Storage(key, value){ return window.localStorage.setItem(key, value); } /*初始化函數(shù)*/ function init(){ var node = new huffman(); $("#submited").click(function (event){ var value = $("#node").val(); if(value!=""){ node.set($("#node").val()); } }); //顯示選取的文件,添加到div中 $("#local").click(function (event){ var len= get_Storage("length"); var text=""; for(var i = 1; i <= len; i++){ text +="
"; } //如果有內(nèi)容就顯示,否則,提示用戶(hù)添加 if(len){ $("#modal-body").html(text); } //選擇本地緩存設(shè)置 $(".item").click(function (event){ var id = $(this).attr("data"); $("#node").val(get_Storage(id)); //設(shè)置flag標(biāo)志 flag=false; $("#close").click(); $("#submited").click(); }); }); }
/*構(gòu)建原型*/ function huffman(){} huffman.prototype={ set:function(value){ if(flag){ if(get_Storage("length")){ var num = parseInt( get_Storage("length"))+1; set_Storage("length", num); }else{ set_Storage("length",1); } set_Storage(get_Storage("length"),value); } }, get:function(){ var i = get_Storage("length"); var array = new Array(); for(p=0; p
夏日小草文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/20654.html
摘要:工作后一直在從事開(kāi)發(fā)從以前的大包大攬到現(xiàn)在的退居服務(wù)端寫(xiě)接口當(dāng)中接觸過(guò)幾個(gè)的接口文檔管理工具或系統(tǒng)簡(jiǎn)單描述下功能全面而且簡(jiǎn)潔有用戶(hù)權(quán)限管理功能支持支持導(dǎo)出有多種文檔模板目錄支持兩級(jí)折疊功能強(qiáng)大權(quán)限管理郵件提醒全文搜索插件管理等重收費(fèi)的一個(gè)文 工作后一直在從事PHP開(kāi)發(fā), 從以前的大包大攬到現(xiàn)在的退居服務(wù)端寫(xiě)接口, 當(dāng)中接觸過(guò)幾個(gè)的接口文檔管理工具或系統(tǒng), 簡(jiǎn)單描述下: showdoc...
小編寫(xiě)這篇文章的主要目的是,教給大家怎么使用哈夫曼編碼,也就是霍夫曼編碼,并把具體的一些代碼實(shí)例給大家貼了出來(lái),希望可以為大家?guī)?lái)幫助?! ∫?、用C語(yǔ)言實(shí)現(xiàn)哈夫曼編碼 1、代碼解釋 ?。?)建立一個(gè)互相連接的表 我們?cè)趧?chuàng)建哈夫曼樹(shù)的過(guò)程之中,要對(duì)互相之間的連接點(diǎn)進(jìn)行增刪查改,所以使用雙向鏈路表格會(huì)更加的容易。'''C #include<stdlib.h>...
閱讀 1165·2021-10-15 09:39
閱讀 3069·2021-09-10 10:50
閱讀 3461·2019-08-30 15:53
閱讀 1889·2019-08-30 15:52
閱讀 2574·2019-08-29 15:31
閱讀 1984·2019-08-26 13:43
閱讀 2605·2019-08-26 13:37
閱讀 1448·2019-08-23 18:31