版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
..數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)題目名稱:huffman編碼與解碼實(shí)現(xiàn)文件的壓縮與解壓專業(yè)年級(jí):組長(zhǎng):小組成員:指導(dǎo)二〇一二年十二月二十六日..目錄目標(biāo)任務(wù)與問(wèn)題分析…………21.1目標(biāo)任務(wù)…………21.2問(wèn)題分析…………2算法分析………22.1構(gòu)造huffman樹(shù)…………………22.1.1字符的統(tǒng)計(jì)………………22.1.2huffman樹(shù)節(jié)點(diǎn)的設(shè)計(jì)……22.2構(gòu)造huffman編碼………………32.2.1huffman編碼的設(shè)計(jì)………32.3壓縮文件與解壓文件的實(shí)現(xiàn)……3三、執(zhí)行效果……43.1界面………43.2每個(gè)字符的編碼…………43.3操作部分…………………53.4文件效果…………………6源程序………………7參考文獻(xiàn)……………16huffman編碼與解碼實(shí)現(xiàn)文件的壓縮與解壓一、目標(biāo)任務(wù)與問(wèn)題分析1.1目標(biāo)任務(wù)采用huffman編碼思想實(shí)現(xiàn)文件的壓縮和解壓功能,可以將任意文件壓縮,壓縮后也可以解壓出來(lái)。這樣即節(jié)約了存儲(chǔ)空間,也不會(huì)破壞文件的完整性。1.2問(wèn)題分析本問(wèn)題首先應(yīng)該是利用哈夫曼思想,對(duì)需要壓縮的文件中的個(gè)字符進(jìn)行頻率統(tǒng)計(jì),為了能對(duì)任意的文件進(jìn)行處理,應(yīng)該所有的文件以二進(jìn)制的方式進(jìn)行處理,即對(duì)文件〔不管包含的是字母還是漢字采取一個(gè)個(gè)的字節(jié)處理,然后根據(jù)統(tǒng)計(jì)的頻率結(jié)果構(gòu)造哈夫曼樹(shù),然后對(duì)每個(gè)字符進(jìn)行哈夫曼編碼,然后逐一對(duì)被壓縮的文件的每個(gè)字符構(gòu)建的新的哈夫曼編碼存入新的文件中即得到的壓縮文件。解壓過(guò)程則利用相應(yīng)的哈夫曼樹(shù)及壓縮文件中的二進(jìn)制碼將編碼序列譯碼,對(duì)文件進(jìn)行解壓,得到解壓文件。二、算法分析2.1構(gòu)造huffman樹(shù)要利用哈夫曼編碼對(duì)文本文件進(jìn)行壓縮,首先必須知道期字符相應(yīng)的哈夫曼編碼。為了得到文件中字符的頻率,一般的做法是掃描整個(gè)文本進(jìn)行統(tǒng)計(jì),編寫(xiě)程序統(tǒng)計(jì)文件中各個(gè)字符出現(xiàn)的頻率。由于一個(gè)字符的范圍在[0-255]之間,即共256個(gè)狀態(tài),所以可以直接用256個(gè)哈夫曼樹(shù)節(jié)點(diǎn)即數(shù)組〔后面有節(jié)點(diǎn)的定義空間來(lái)存儲(chǔ)整個(gè)文件的信息,節(jié)點(diǎn)中包括對(duì)應(yīng)字符信息,其中包括頻率。2.1.1字符的統(tǒng)計(jì)用結(jié)構(gòu)體huffchar來(lái)存放文件字符的信息。其中有文件中不同字符出現(xiàn)的種類Count、字符data。structhuffchar{//存放讀入字符的類;intCount;//字符出現(xiàn)的個(gè)數(shù);chardata;//字符;};函數(shù)實(shí)現(xiàn):boolchar_judge<charc>//判斷字符出現(xiàn)的函數(shù);voidchar_add<charc>//添加新出現(xiàn)的字符;voidread_file_count<>//文件的讀取2.1.2huffman樹(shù)節(jié)點(diǎn)的設(shè)計(jì)用結(jié)構(gòu)體huff_tree來(lái)存儲(chǔ)結(jié)點(diǎn)信息,其中有成員頻率weight、父親節(jié)點(diǎn)parent、左兒子節(jié)點(diǎn)lchild、右兒子節(jié)點(diǎn)rchild。structhuff_tree{//huffman樹(shù)結(jié)點(diǎn)定義;intparent;intlchild;intrchild;intweight;};函數(shù)實(shí)現(xiàn):voidcreathuffman<>//構(gòu)造huffman樹(shù)的函數(shù)2.2構(gòu)造huffman編碼2.2.1huffman編碼的設(shè)計(jì)用結(jié)構(gòu)體huffcode來(lái)存儲(chǔ)每個(gè)字符的編碼。其中有編碼數(shù)組bits、起始編碼start、頻數(shù)count、編碼對(duì)應(yīng)的字符c。structhuffcode{//結(jié)構(gòu)體stringbits[100];//存放解碼;intstart;//intcount;//頻數(shù)stringc;//存放字符;};函數(shù)實(shí)現(xiàn):voidhuffmancode<>//編碼函數(shù)2.3壓縮文件與解壓文件的實(shí)現(xiàn)將壓縮的文件根據(jù)huffman樹(shù)進(jìn)行編碼,存入新的文件〔huffman1.txt中,將huffman.txt按照huffman編碼對(duì)應(yīng)的字符解壓回來(lái),但是這樣的文件是壓縮不了的,當(dāng)時(shí)用了一個(gè)30kb的文件壓縮后竟然成了119kb,導(dǎo)致這樣的問(wèn)題是因?yàn)橐粋€(gè)字符對(duì)應(yīng)幾個(gè)二進(jìn)制數(shù)字,然而一個(gè)二進(jìn)制文字也是占一個(gè)字節(jié),這就導(dǎo)致了壓縮后的文件變大。處理的方法將huffman1.txt文件中的二進(jìn)制編碼7位7位的存成一個(gè)ascII值存入新的文件,這樣就實(shí)現(xiàn)了真正打壓縮。解壓的時(shí)候?qū)⑽募械腶scII值重新弄成二進(jìn)制,不夠7位的前邊補(bǔ)0,例如ascII值為99的二進(jìn)制位100011這是6位的ascII碼所以再前邊補(bǔ)一個(gè)0那么99的二進(jìn)制就變成0100011。接下來(lái)就利用huffman編碼將這個(gè)文件重新譯碼過(guò)來(lái)。函數(shù)實(shí)現(xiàn):voidcode_huffman_file<>//編碼后的二進(jìn)制碼存入文件voidcode_file_out<>//將編碼過(guò)的文件恢復(fù);voidevaluating<>//比較文件壓縮的比例voidchange<>//將二進(jìn)制編碼變成ascII碼voidyichu<>//將ascII翻譯成二進(jìn)制碼恢復(fù)文件三、執(zhí)行效果本算法有一個(gè)初始文件為huffman.txt。為一篇小說(shuō),大小為32KB3.1界面3.2每個(gè)字符的編碼3.3操作部分3.4文件效果huffman為初始文件大小為30KB,huffman1為二進(jìn)制編碼文件大小為130KB,huffman2文件為解壓后的文件大小為30KB,huffman3.為真正壓縮后的文件大小為19KB,huffman為huffman3文件解壓后的文件大小為30KB,與huffman文件內(nèi)容相同。標(biāo)記的文件就是壓縮后的huffman3文件。四、源程序:#include<iostream>#include<fstream>#include<string>#include<iomanip>#include<cstdio>#include<algorithm>#include<queue>usingnamespacestd;stringremfile[3100000];//存放原文件字符的數(shù)組;charstrstr[1500000];intremcount=0;//記錄元素個(gè)數(shù);floatbitecount=0;//記錄二進(jìn)制碼的個(gè)數(shù);/****************************************************************/structhuffchar{//存放讀入字符的類;intCount;//字符出現(xiàn)的個(gè)數(shù);chardata;//字符;};intCount=1;//記錄huff數(shù)組中字符實(shí)際出現(xiàn)的個(gè)數(shù);huffcharhuff[1000];//類的對(duì)象;/****************************************************************//*文件讀入部分和統(tǒng)計(jì)字符出現(xiàn)的頻率*/boolchar_judge<charc>//判斷字符出現(xiàn)的函數(shù);{for<inti=1;i<=Count;i++>if<huff[i].data==c>{huff[i].Count++;returntrue;}//如果出現(xiàn)過(guò),出現(xiàn)的頻數(shù)加1;returnfalse;}voidchar_add<charc>//添加新出現(xiàn)的字符;{huff[Count].data=c;huff[Count++].Count++;//個(gè)數(shù)增加,}//文件的讀取voidread_file_count<>{charc;ifstreaminfile;infile.open<"huffman.txt">;//打開(kāi)huffman.txt文件;if<!infile>//檢查文件是否打開(kāi)。{cerr<<"不能打開(kāi)huffman.txt文件";//輸出文件未打開(kāi)的標(biāo)志。exit<0>;}cout<<"讀入的文件中的內(nèi)容為:"<<endl;while<<c=infile.get<>>!=EOF>{remfile[++remcount]=c;if<!char_judge<c>>char_add<c>;}cout<<endl;}/******************文件讀入和統(tǒng)計(jì)字符出現(xiàn)頻率部分結(jié)束**************//******************************************************************//******************構(gòu)造huffman樹(shù)程序部分***************************/structhuff_tree{//huffman樹(shù)結(jié)點(diǎn)定義;intparent;intlchild;intrchild;intweight;};intsum;//huffman樹(shù)中結(jié)點(diǎn)的個(gè)數(shù);huff_treehuffman[1000];voidcreathuffman<>//構(gòu)造huffman樹(shù)的函數(shù){intmin1,min2;//指示權(quán)值最小;intloc1,loc2;//指向權(quán)值最小的兩個(gè)數(shù)的位置;for<inti=1;i<=sum;i++>{//對(duì)huffman樹(shù)的結(jié)點(diǎn)進(jìn)行初始化;huffman[i].parent=0;huffman[i].lchild=0;huffman[i].rchild=0;huffman[i].weight=0;}for<intii=1;ii<Count;ii++>//將權(quán)值賦給huffman[].weight;huffman[ii].weight=huff[ii].Count;sum=2*Count-3;for<intj=Count;j<=sum;j++>{loc1=loc2=0;//權(quán)值最小的min1=min2=2000000;for<intk=1;k<=j-1;k++>//求權(quán)值最小的兩個(gè)地址;if<huffman[k].parent==0>if<huffman[k].weight<=min1>{min2=min1;min1=huffman[k].weight;loc2=loc1;loc1=k;}elseif<huffman[k].weight<=min2>{min2=huffman[k].weight;loc2=k;}////////////將求出的兩個(gè)權(quán)值最小的結(jié)點(diǎn)合并為新的結(jié)點(diǎn),并將新的結(jié)點(diǎn)存入數(shù)組中huffman[loc1].parent=j;huffman[loc2].parent=j;huffman[j].lchild=loc1;huffman[j].rchild=loc2;huffman[j].weight=huffman[loc1].weight+huffman[loc2].weight;}}/*******************************構(gòu)造huffman樹(shù)的程序部分結(jié)束********************************//*************************************huffman編碼開(kāi)始**************************************/structhuffcode{//結(jié)構(gòu)體stringbits[100];//存放解碼;intstart;//intcount;//頻數(shù)stringc;//存放字符;};huffcodehcode[100];voidhuffmancode<>//編碼函數(shù){intrem,p;intcount1=0;for<inty=1;y<=Count;y++>{//編碼部分;rem=y;hcode[y].start=sum;hcode[y].c=huff[y].data;p=huffman[y].parent;while<p!=0>{if<huffman[p].lchild==rem>hcode[y].bits[++count1]='0';elsehcode[y].bits[++count1]='1';rem=p;p=huffman[p].parent;}hcode[y].count=count1;count1=0;}cout<<"字符以及其編碼:"<<endl;for<intt=1;t<=Count;t++>//輸出所編的碼;{cout<<"字符"<<hcode[t].c<<";編碼:";intr=hcode[t].count;while<r>cout<<hcode[t].bits[r--];cout<<endl;}}/************************************************************************************/stringstr;voidcode_huffman_file<>{ofstreamfp;cout<<"請(qǐng)輸入文件名"<<endl<<"例如:huffman1.txt"<<endl;cout<<"該文件用來(lái)存放編碼后的文件即壓縮文件"<<endl;cin>>str;fp.open<str.c_str<>>;if<!fp>//檢查文件是否打開(kāi)。{cerr<<"不能打開(kāi)"<<str<<"文件"<<endl;//輸出文件未打開(kāi)的標(biāo)志。exit<0>;}for<intj=1;j<=remcount;j++>{for<inti=1;i<=Count;i++>if<remfile[j]==hcode[i].c>{for<intk=hcode[i].count;k>0;k-->{fp<<hcode[i].bits[k];bitecount++;}break;}}fp.close<>;}/****************************編碼并將編碼存入文件部分結(jié)束*************************/strings1;/////////////////////////////////////////////////////////////////////////////////voidcode_file_out<>//將編碼過(guò)的文件恢復(fù);{ifstreamfp1;//編碼文件;ofstreamfp2;//解壓縮文件;fp1.open<str.c_str<>>;if<!fp1>//檢查文件是否打開(kāi)。{cerr<<"不能打開(kāi)"<<str<<"文件"<<endl;//輸出文件未打開(kāi)的標(biāo)志。exit<0>;}charinchar;cout<<"請(qǐng)輸入文件名"<<endl<<"例如:huffman2.txt"<<endl;cout<<"該文件用來(lái)存放解壓后的文件"<<endl;cin>>s1;fp2.open<s1.c_str<>>;if<!fp2>//檢查文件是否打開(kāi)。{cerr<<"不能打開(kāi)"<<s1<<"文件"<<endl;//輸出文件未打開(kāi)的標(biāo)志。exit<0>;}for<intptr=sum;!fp1.eof<>;>//將編碼轉(zhuǎn)為字符輸入的到文件中;{fp1>>inchar;if<inchar=='1'>ptr=huffman[ptr].rchild;//查找相應(yīng)編碼對(duì)應(yīng)huffman樹(shù)中的位置,elseptr=huffman[ptr].lchild;if<huffman[ptr].rchild==0&&huffman[ptr].lchild==0>//判斷是否為葉子結(jié)點(diǎn);{fp2<<huff[ptr].data;ptr=sum;}//是葉子結(jié)點(diǎn),將該結(jié)點(diǎn)的對(duì)應(yīng)字符輸入到文件中;}cout<<endl<<"請(qǐng)檢查原文件"<<"huffman.txt"<<"與解壓縮文件"<<s1<<endl<<endl<<endl;//cout<<"*********************************請(qǐng)檢查*****************************"<<endl;}/*************************解壓縮文件部分結(jié)束**************************************/voidevaluating<>{floaty1;y1=bitecount/7/remcount*100;cout<<"壓縮比例是:"<<y1<<"%"<<endl;}strings2;//壓縮文件2名inttot=0;voidchange<>{ifstreamfp1;ofstreamfp2;fp1.open<str.c_str<>>;if<!fp1>//檢查文件是否打開(kāi)。{cerr<<"不能打開(kāi)"<<s1<<"文件"<<endl;//輸出文件未打開(kāi)的標(biāo)志。exit<0>;}cout<<"輸入文件名用來(lái)存放壓縮后的文件"<<endl<<"例如huffman3.txt"<<endl;cin>>s2;charinchar,ch;fp2.open<s2.c_str<>>;if<!fp2>//檢查文件是否打開(kāi)。{cerr<<"不能打開(kāi)"<<s2<<"文件"<<endl;//輸出文件未打開(kāi)的標(biāo)志。exit<0>;}intt=0,f=0,s;//chara[8];while<!fp1.eof<>>{fp1>>inchar;s=inchar-'0';t*=2;t+=s;f++;if<f==7>{ch=t;t=0;fp2<<ch;strstr[tot++]=ch;f=0;}}strstr[tot]='\0';fp1.close<>;fp2.close<>;}strings3;//文件解壓2名queue<int>s;strings4;voidyichu<>{ifstreamfp1;ofstreamfp2;fp1.open<s2.c_str<>>;if<!fp1>//檢查文件是否打開(kāi)。{cerr<<"不能打開(kāi)"<<s2<<"文件"<<endl;//輸出文件未打開(kāi)的標(biāo)志。exit<0>;}cout<<"輸入文件名用來(lái)存放解壓后的文件"<<endl<<"例如huffman4.txt"<<endl;cin>>s3;fp2.open<s3.c_str<>>;if<!fp2>//檢查文件是否打開(kāi)。{cout<<"不能打開(kāi)"<<s3<<"文件"<<endl;//輸出文件未打開(kāi)的標(biāo)志。exit<0>;}intinchar;inti=0;while<!s.empty<>>s.pop<>;for<intptr=sum;i<tot;>{if<s.size<><3>{charch;intnum,a[8];fp1>>ch;ch=strstr[i++];num=ch;for<inti=6;i>=0;i-->{a[i]=num%2;num/=2;}for<inti=0;i<7;i++>{//ch=a[i]+'0';s.push<a[i]>;}}inchar=s.front<>;s.pop<>;if<inchar==1>ptr=huffman[ptr].rchild;//查找相應(yīng)編碼對(duì)應(yīng)huffman樹(shù)中的位置,elseptr=huffman[ptr].lchild;if<huffman[ptr].lchild==0&&huffman[ptr].rchild==0>//判斷是否為葉子結(jié)點(diǎn);{fp2<<huff[ptr].data;ptr=sum;}//是葉子結(jié)點(diǎn),將該結(jié)點(diǎn)的對(duì)應(yīng)字符輸入到文件中;}fp1.close<>;fp2.close<>;//printf<"****">;}intmain<>{cout<<"***************
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 高效的采購(gòu)合同解讀
- 陶瓷杯采購(gòu)合同
- 項(xiàng)目申報(bào)合作服務(wù)合同
- 永州市房產(chǎn)買賣合同
- 城市回遷房合同范本樣本
- 家庭花卉訂購(gòu)合同
- 新版房屋買賣合同版版
- 中介公司服務(wù)協(xié)議
- 現(xiàn)金贖樓服務(wù)合同還款還款優(yōu)惠政策
- 土地?fù)?dān)保合同協(xié)議范例
- 糖果行業(yè)大數(shù)據(jù)分析-洞察分析
- 往來(lái)沖賬合同范例
- 工裝墊資合同范例
- 人教版九年級(jí)化學(xué)上冊(cè)期末復(fù)習(xí)計(jì)算題鞏固(含答案)
- 湖北省荊門市(2024年-2025年小學(xué)六年級(jí)語(yǔ)文)統(tǒng)編版質(zhì)量測(cè)試(上學(xué)期)試卷及答案
- 2022年四川省眉山市公開(kāi)招聘警務(wù)輔助人員(輔警)筆試專項(xiàng)訓(xùn)練題試卷(3)含答案
- 重慶第二師范學(xué)院《管理學(xué)導(dǎo)論》2021-2022學(xué)年第一學(xué)期期末試卷
- 剪輯師的職業(yè)規(guī)劃
- 土木工程CAD-終結(jié)性考核-國(guó)開(kāi)(SC)-參考資料
- 2024年醫(yī)院法律法規(guī)培訓(xùn):提升醫(yī)務(wù)人員法律意識(shí)
- 種植檳榔合作合同模板
評(píng)論
0/150
提交評(píng)論