Ⅰ 利用哈夫曼編碼進行壓縮壓縮率一般達到多少
哈夫曼編碼進行壓縮的壓縮率是根據平均碼長來計算的,壓縮率比較低。
例如:用三位二進行數進行的等長編碼平均長度為3,而根據哈夫曼樹編碼的平均碼長為:
4*0.07+2*0.19+5*0.02+4*0.06+2*0.32+5*0.03+2*0.21+4*0.10=2.61
2.61/3=0.87=87%
其平均碼長是等長碼的87%,所以平均壓縮率為13%。
哈夫曼編碼,又稱霍夫曼編碼,是一種編碼方式,哈夫曼編碼是可變字長編碼(VLC)的一種。
Huffman於1952年提出一種編碼方法,該方法完全依據字元出現概率來構造異字頭的平均長度最短的碼字,有時稱之為最佳編碼,一般就叫做Huffman編碼(有時也稱為霍夫曼編碼)。
壓縮率,描述壓縮文件的效果名,是文件壓縮後的大小與壓縮前的大小之比,例如:把100m的文件壓縮後是90m,壓縮率為90/100*100%=90%,壓縮率一般是越小越好,但是壓得越小,解壓時間越長。
(1)哈夫曼編程什麼意思擴展閱讀
哈夫曼編碼的具體方法:先按出現的概率大小排隊,把兩個最小的概率相加,作為新的概率
和剩餘的概率重新排隊,再把最小的兩個概率相加,再重新排隊,直到最後變成1。
每次相
加時都將「0」和「1」賦與相加的兩個概率,讀出時由該符號開始一直走到最後的「1」,
將路線上所遇到的「0」和「1」按最低位到最高位的順序排好,就是該符號的哈夫曼編碼。
參考資料來源:網路-哈夫曼編碼
參考資料來源:網路-壓縮率
Ⅱ 鍝堝か鏇肩紪鐮/璇戠爜鍣ㄧ紪紼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 10000 //瀹氫箟瀛楃︿覆鏈澶ч暱搴
#define N 128 //瀹氫箟鍙跺瓙鑺傜偣涓鏁
typedef struct node //瀹氫箟鍝堝か鏇兼爲鑺傜偣緇撴瀯浣
{
int weight;
struct node *LChild,*RChild,*Parent; //鍒嗗埆鎸囧悜璇ヨ妭鐐圭殑宸﹀╁瓙錛屽彸瀛╁瓙錛屽拰鍙屼翰鑺傜偣
struct node *next; //鎸囧悜寤虹珛鐨勫搱澶鏇兼爲鐨勪笅涓涓鑺傜偣
}HFMNode,*HFMTree;
typedef struct //瀹氫箟鍝堝か鏇肩紪鐮佺殑緇撴瀯浣
{
char ch; //瀛樺偍瀵瑰簲鐨勫瓧絎
char code[N+1]; //瀛樺偍瀵瑰簲瀛楃︾殑緙栫爜
int start; //瀛樺偍緙栫爜鐨勮搗濮嬩綅緗
}CodeNode;int n; //瀛樺偍鐪熸e彾瀛愯妭鐐逛釜鏁
void clearscreen()
{
system("cls");
}
void Open(char s[]) //鎵撳紑瀛樻斁瀛楃︽垨緙栫爜鐨勬枃浠訛紝灝嗗叾瀛樺叆瀛楃︿覆鏁扮粍涓
{
char name[10];
FILE *fp;
int i=0;
printf("璇瘋緭鍏ヨ佹墦寮鐨勬枃浠跺悕錛");
gets(name); //瑕佹墦寮鐨勬枃浠跺悕
if((fp=fopen(name,"rt"))==NULL)
{
printf("鎵撳紑澶辮觸錛\n"); //鑻ユ墦寮澶辮觸錛屽垯鐩存帴閫鍑
exit(1);
}
s[i++]=fgetc(fp);
while(s[i-1]!=EOF)
s[i++]=fgetc(fp);
s[i]='\0'; //瀛樺彇瀛楃︿覆緇撴潫
fclose(fp);
}
void Save(char s[]) //淇濆瓨瀛楃︽垨緙栫爜鍒版枃浠朵腑
{
char name[10];
FILE *fp;
printf("璇瘋緭鍏ヨ佷繚瀛樼殑鏂囦歡鍚嶏細");
gets(name);
if((fp=fopen(name,"wt"))==NULL)
{
printf("瀛樺偍澶辮觸錛");
exit(1);
}
fputs(s,fp);
printf("\n淇濆瓨鎴愬姛錛屾枃浠跺悕涓:%s銆\n",name);
printf("\n鎸夊洖杞﹂敭緇х畫...");
getchar();
fclose(fp);} void SearchStr(char s[],char str[],int count[])
{
//鏌ユ壘瀛楃︿覆涓瀛楃︾殑涓鏁板拰姣忎釜瀛楃﹀嚭鐜扮殑嬈℃暟
int i,j,k=0;
for(i=0;i<N;i++) //鍒濆嬪寲姣忎釜瀛楃﹀嚭鐜扮殑嬈℃暟
count[i]=0;
for(i=0;s[i];i++)
{
for(j=0;j<k;j++) //鍦╯tr[]涓鏌ユ壘鏄鍚︽湁璇ュ瓧絎
if(str[j]==s[i])
{
count[j]++;
break;
}
if(j==k) //鍦╯tr[]涓鏃犺ュ瓧絎︼紝灝嗗叾瀛樺叆鏈鍚庝竴涓鍗曞厓
{
str[k]=s[i];
count[k++]++;
}
}
str[k]='\0'; //灝嗗瓧絎︿覆緇撳熬緗\0
n=k; //灝嗗疄闄呯殑瀛楃︿釜鏁頒綔涓哄彾瀛愯妭鐐逛釜鏁板瓨鍏n
}void SelectMin(HFMTree HT,int k,HFMTree *HT1,HFMTree *HT2)
{
//鏌ユ壘鍝堝か鏇奸摼琛ㄤ腑涓や釜鏉冨兼渶灝忕殑鑺傜偣
int i,min;
HFMTree p;
min=32767;
for(i=0,p=HT;i<k;i++,p=p->next)
if(p->weight<min&&p->Parent==0)
{
min=p->weight;
*HT1=p;
}
min=32767;
for(i=0,p=HT;i<k;i++,p=p->next)
if(p->weight<min&&p->Parent==0&&p!=*HT1) //浠ょ浜屼釜鏈灝忕殑鑺傜偣涓嶇瓑浜庣涓涓鑺傜偣
{
min=p->weight;
*HT2=p;
}}
void CreatHFMTree(HFMTree *HT,int count[])
{
//鍒涘緩鍝堝か鏇兼爲
int i;
HFMTree p,HT1,HT2; //HT1錛孒T2鍒嗗埆瀛樻斁鏉冨兼渶灝忓拰嬈″皬鐨勮妭鐐圭殑浣嶇疆
p=*HT=(HFMTree)malloc(sizeof(HFMNode));
p->next=p->LChild=p->RChild=p->Parent=NULL; //鍒濆嬪寲鍝堝か鏇奸摼琛ㄤ笖鏈2n-1涓鑺傜偣
for(i=1;i<2*n-1;i++)
{
p->next=(HFMTree)malloc(sizeof(HFMNode));
p=p->next;
p->next=p->LChild=p->RChild=p->Parent=NULL;
}for(i=0,p=*HT;i<n;i++) //灝嗗悇涓瀛楃﹀嚭鐜扮殑嬈℃暟浣滀負鏉冨
{ //瀛樺叆鍝堝か鏇奸摼琛ㄧ殑鍓峮涓鍗曞厓涓
p->weight=count[i];
p=p->next;
}for(i=n;i<2*n-1;i++) //灝嗗悗n-1涓鑺傜偣璧嬫潈鍊礆紝寤烘爲
{
SelectMin(*HT,i,&HT1,&HT2); //姣忔′粠鍓嶢涓鑺傜偣涓閫夊彇鏉冨兼渶灝忕殑涓や釜鑺傜偣
HT1->Parent=HT2->Parent=p;
p->LChild=HT1;
p->RChild=HT2;
p->weight=HT1->weight+HT2->weight; //灝嗕袱涓鑺傜偣鐨勬潈鍊肩浉鍔犲瓨鍏ユ渶鍚庝竴涓鑺傜偣涓
p=p->next; //p鎸囧悜涓嬩竴涓娌℃湁瀛樺偍鏉冨肩殑鑺傜偣
}}
void HFMCode(HFMTree HT,CodeNode HC[],char str[])
{
//浠庢瘡涓鍙跺瓙鑺傜偣寮濮嬶紝鍒╃敤鍝堝か鏇兼爲瀵規瘡涓瀛楃﹁繘琛岀紪鐮侊紝鏈緇堝緩絝嬩竴涓鍝堝か鏇艱〃
int i;
HFMTree q,p=HT;
for(i=0;i<n;i++) //灝嗗瓧絎﹀瓨鍏ュ搱澶鏇肩紪鐮佺粨鏋勪綋鏁扮粍鐨勫瓧絎﹀崟鍏冧腑
{
HC[i].ch=str[i];
HC[i].code[n-1]='\0'; //鍒濆嬪寲緙栫爜鐨勬渶鍚庝竴浣
}
for(i=0;i<n;i++)
{
HC[i].start=n-1;
for(q=p;q->Parent;q=q->Parent) //鍒ゆ柇q鎵鎸囧悜鐨勮妭鐐癸紝宸﹀╁瓙緗0錛屽彸瀛╁瓙緗1
if(q==q->Parent->LChild)
HC[i].code[--HC[i].start]='0';
else HC[i].code[--HC[i].start]='1';
p=p->next; //鍒ゆ柇涓嬩竴涓鍙跺瓙鑺傜偣
}
}
void TotalCoding(char s[],CodeNode HC[],char code[])
{
//鍒╃敤鍝堝か鏇肩紪鐮佽〃瀵規暣涓瀛楃︿覆榪涜岀紪鐮
int i,j;
code[0]='\0'; //緙栫爜鏁扮粍鍒濆嬪寲
for(i=0;s[i];i++) //灝嗘瘡涓瀛楃﹀湪鍝堝か鏇肩紪鐮佽〃涓瀵瑰簲鐨勭紪鐮佸瓨鍏ュ瓨鏀炬葷紪鐮佺殑鏁扮粍涓
for(j=0;j<n;j++)
if(s[i]==HC[j].ch)
strcpy(code+strlen(code),HC[j].code+HC[j].start);
}void DeCoding(char code[],HFMTree HT,char str[],char s[])
{
//瀵瑰搱澶鏇肩紪鐮佽繘琛岃В鐮侊紝鏀懼叆瀛楃︿覆s涓
int i,j,k=0;
HFMTree root,p,q;
for(root=HT;root->Parent;root=root->Parent); //鐢╮oot鎸囧悜鍝堝か鏇兼爲鐨勬牴緇撶偣
for(i=0,p=root;code[i];i++) //浠庢牴緇撶偣寮濮嬫寜緙栫爜欏哄簭璁塊棶鏍
{
if(code[i]=='0')
p=p->LChild;
else p=p->RChild;
if(p->LChild==NULL&&p->RChild==NULL) //鍒版牴鑺傜偣鏃跺皢璇ヨ妭鐐瑰瑰簲鐨勫瓧絎﹁緭鍑
{
for(j=0,q=HT;q!=p;q=q->next,j++);
s[k++]=str[j];
p=root; //鍥炴函鍒版牴緇撶偣
}
}
s[k]='\0'; //瑙g爜瀹屾瘯錛屽湪瀛楃︿覆鏈鍚庝竴涓鍗曞厓瀛樺叆'\0'
}
void Coding(char s[],char str[],char code[],int count[],HFMTree *HT,CodeNode HC[])
{
clearscreen();
printf("\n鎵撳紑瀛樻斁瀛楃︿覆鐨勬枃浠...\n\n");
Open(s); //鎵撳紑婧愮爜鏂囦歡
SearchStr(s,str,count); //鏌ユ壘瀛楃︿覆涓涓嶅悓鐨勫瓧絎﹀強鍏跺嚭鐜扮殑嬈℃暟
CreatHFMTree(HT,count); //鐢ㄦ瘡涓瀛楃﹀嚭鐜扮殑嬈℃暟浣滀負鍙跺瓙鑺傜偣鐨勬潈鍊煎緩絝嬪搱澶鏇兼爲
HFMCode(*HT,HC,str); //鍒╃敤鍝堝か鏇兼爲瀵規瘡涓鍙跺瓙鑺傜偣榪涜岀紪鐮侊紝瀛樺叆緙栫爜琛ㄤ腑
TotalCoding(s,HC,code); //鍒╃敤緙栫爜琛ㄥ瑰瓧絎︿覆榪涜屾渶緇堢紪鐮
printf("\n璇誨叆鐨勫瓧絎︿覆涓:\n");
puts(s);
printf("\n鏈緇堢殑鍝堝か鏇肩紪鐮佹槸:\n");
puts(code);
printf("\n淇濆瓨緙栫爜,");
Save(code); //淇濆瓨鏈緇堢殑鍝堝か鏇肩紪鐮
}
void TransCode(char code[],char str[],char ss[],HFMTree *HT,CodeNode HC[])
{
clearscreen();
printf("\n鎵撳紑緙栫爜鐨勬枃浠...\n\n");
Open(code); //鎵撳紑緙栫爜鏂囦歡
DeCoding(code,*HT,str,ss); //灝嗙紪鐮佽繘琛岃В鐮佸瓨鍏ュ瓧絎︿覆鏁扮粍ss[]涓
printf("\n寰楀埌鐨勬渶緇堝瓧絎︿覆涓:\n");
puts(ss);
printf("\n淇濆瓨璇戠爜錛");
Save(ss); //淇濆瓨璇戠爜鍚庣殑瀛楃︿覆
}void main()
{
//涓誨嚱鏁
char s[M],ss[M]; //瀹氫箟瀛楃︿覆鏁扮粍錛宻[]瀛樻斁灝嗚佺紪鐮佺殑瀛楃︿覆錛宻s[]瀛樿В鐮佸悗鐨勫瓧絎︿覆
char str[N]; //瀛樻斁杈撳叆鐨勫瓧絎︿覆涓璶涓涓嶅悓鐨勫瓧絎
int count[N]; //瀛樻斁n涓涓嶅悓瀛楃﹀瑰簲鐨勫湪鍘熷瓧絎︿覆涓鍑虹幇鐨勬℃暟
char code[M]; //瀛樻斁鏈緇堢紪鐮佸畬鎴愬悗鐨勭紪鐮
char choice;
HFMTree HT; //瀹氫箟涓涓鍝堝か鏇兼爲鐨勯摼琛
CodeNode HC[N]; //瀹氫箟涓涓鍝堝か鏇肩紪鐮佽〃鐨勬暟緇勶紝瀛樻斁姣忎釜瀛楃﹀瑰簲鐨勫搱澶鏇肩紪鐮
do
{
clearscreen();
printf("\n\n");
printf(" ************鍝堝か鏇兼爲************\n");
printf(" ** **\n");
printf(" ** 1.緙栫爜銆 **\n");
printf(" ** 2.璇戠爜銆 **\n");
printf(" ** 0.閫鍑恆 **\n");
printf(" ** **\n");
printf(" ** **\n");
printf(" ** **\n");
printf(" ** 璇瘋緭鍏ョ浉搴旀搷浣滅殑搴忓彿(0-2) **\n");
printf(" ********************************\n");
scanf("%c",&choice);
getchar();
switch(choice)
{
case '1': Coding(s,str,code,count,&HT,HC);break; //瀵瑰瓧絎︿覆榪涜岀紪鐮
case '2': TransCode(code,str,ss,&HT,HC);break; //瀵圭紪鐮佽繘琛岃В鐮
case '0': break;
default : printf(" 杈撳叆閿欒錛佽烽噸鏂拌緭鍏ワ紒\n");
}
}while(choice!='0');
}
Ⅲ 鍝堝か鏇肩紪鐮佺爜闀挎庝箞綆
璁炬煇淇℃簮浜х敓鏈変簲縐嶇﹀彿u1銆乽2銆乽3銆乽4鍜寀5錛屽瑰簲姒傜巼P1=0.4錛孭2=0.1錛孭3=P4=0.2錛孭5=0.1銆
闇嶅か鏇肩紪鐮佹槸鍙橀暱緙栫爜錛屾濊礬錛氬規傜巼澶х殑緙栫殑鐮佸瓧鐭錛屾傜巼灝忕殑緙栫殑鐮佸瓧闀匡紝榪欐牱涓鏉ユ墍緙栫殑鎬葷爜闀垮氨灝忥紝榪欐牱緙栫爜鏁堢巼灝遍珮銆備笂闈㈤偅鏍鋒眰鏄涓嶅圭殑錛岄櫎闈炰綘榪6涓鐮佸瓧鏄絳夋傜巼鐨勶紝鍚勫崰1/6銆傚簲璇ョ敤瀵瑰簲鐨勬傜巼*鍏跺瑰簲寰楃爜闀匡紝鍐嶆眰鍜屻
瀹為檯搴旂敤涓
闄ら噰鐢ㄥ畾鏃舵竻媧椾互娑堥櫎璇宸鎵╂暎鍜岄噰鐢ㄧ紦鍐插瓨鍌ㄤ互瑙e喅閫熺巼鍖歸厤浠ュ栵紝涓昏侀棶棰樻槸瑙e喅灝忕﹀彿闆嗗悎鐨勭粺璁″尮閰嶏紝渚嬪傞粦錛1錛夈佺櫧錛0錛変紶鐪熶俊婧愮殑緇熻″尮閰嶏紝閲囩敤0鍜1涓嶅悓闀垮害娓哥▼緇勬垚鎵╁ぇ鐨勭﹀彿闆嗗悎淇℃簮銆傛父紼嬶紝鎸囩浉鍚鐮佸厓鐨勯暱搴︼紙濡備簩榪涚爜涓榪炵畫鐨勪竴涓0鎴栦竴涓1鐨勯暱搴︽垨涓鏁幫級銆
鎸夌収CCITT鏍囧噯錛岄渶瑕佺粺璁2脳1728縐嶆父紼嬶紙闀垮害錛夛紝榪欐牱錛屽疄鐜版椂鐨勫瓨鍌ㄩ噺澶澶с備簨瀹炰笂闀挎父紼嬬殑姒傜巼寰堝皬錛屾晠CCITT榪樿勫畾錛氳嫢l琛ㄧず娓哥▼闀垮害錛屽垯l=64q+r銆