Ⅰ 利用哈夫曼编码进行压缩压缩率一般达到多少
哈夫曼编码进行压缩的压缩率是根据平均码长来计算的,压缩率比较低。
例如:用三位二进行数进行的等长编码平均长度为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銆