关于哈夫曼压缩
我写了一个哈夫曼压缩压缩率不高 求大神指导。
我哈夫曼树和编码都构建成功着 , 只是我写压缩文件的时候是把对应的字符和这个字符对应的串长存进去的,在把串长对应顺序的哈夫曼编码存进去,最后对照着要压缩的文件的字母顺序把哈夫曼编码存进去。 因为我考虑到字符对应的编码串长肯定能用一个字符存进去加上它对应的编码长度也肯定也超不过4个字节 而我如果存取这个字符的权值的话,要占用四个字节 我认为我这种方法应该会提高压缩率的 我也没对比 现在我测试 压缩率很低 求解。。。。。。
[解决办法]
按位存储.
[解决办法]
- C/C++ code
#include <stdio.h>#include <string.h>#define n 100#define m 2*n-1typedef struct{ char ch; char bits[9]; int len;}CodeNode;typedef CodeNode HuffmanCode[n+1];typedef struct{ int weight; int lchild,rchild,parent;}HTNode;typedef HTNode HuffmanTree[m+1];int num;void selectHT(HuffmanTree T,int k ,int &s1,int &s2){ int i,j; int min1 = 101; for(i = 1;i <= k;i++) if(T[i].weight < min1&&T[i].parent == 0) { j = i; min1 = T[i].weight; } s1 = j; min1 = 32767; for(i = 1;i <= k;i++) if(T[i].weight < min1&&T[i].parent == 0&&i != s1) { j = i; min1 = T[i].weight; } s2 = j;}int jsq(char *s,int cnt[],char str[]){ //统计各字符串中各种字母的个数以及字符的种类 char * p; int i,j,k; int temp[27]; for(i = 1;i <= 26;i++) temp[i] = 0; for(p = s;*p != '\0';p++) {//统计各种字符个数 if(*p>='A' && *p <= 'Z') { k = *p - 64; temp[k]++; } } j = 0; for(i = 1,j = 0;i <= 26;i++)//统计有多少种字符 if(temp[i] != 0) { j++; str[j] = i + 64; //送对应的字母到数组中 cnt[j] = temp[i]; //存入对应字母权值 } return j;}void CreHuffmanTree(HuffmanTree HT,HuffmanCode HC,int cnt[],char str[]){ int i,s1,s2; for(i = 1;i <= 2*num -1;i++) { HT[i].lchild = 0; HT[i].rchild = 0; HT[i].parent = 0; HT[i].weight = 0; } for(i = 1;i <= num;i++) HT[i].weight = cnt[i]; for(i = num + 1;i <= 2*num -1;i++) { selectHT(HT,i - 1,s1,s2); HT[s1].parent = i; HT[s2].parent = i; HT[i].lchild = s1; HT[i].rchild = s2; HT[i].weight = HT[s1].weight + HT[s2].weight; } for(i = 0;i <= num;i++) HC[i].ch = str[i]; i = 1; while(i <= num) { printf("字符%c,次数为:%d\n",HC[i].ch,cnt[i++]); }}void HuffmanEncoding(HuffmanTree HT,HuffmanCode HC){ int c,p,i; char cd[n]; int start; cd[num] = '\0'; for(i = 1;i <= num;i++) { start = num; c = i; while((p = HT[c].parent) > 0) { cd[--start] = (HT[p].lchild == c)?'0':'1'; c = p; } strcpy(HC[i].bits,&cd[start]); HC[i].len = num - start; }}void coding(HuffmanCode HC,char *str){ int i,j; FILE *fp; fp = fopen("codefile.txt","w"); while(*str) { for(i = 1;i <= num;i++) { if(HC[i].ch == *str) { for(j = 0;j < HC[i].len;j++) fputc(HC[i].bits[j],fp); break; } } str++; } fclose(fp);}char * decode(HuffmanCode HC){ FILE *fp; char str[254]; char *p; static char cd[n+1]; int i,j,k = 0,cjs; fp = fopen("codefile.txt","r"); while(!feof(fp)) { cjs = 0; for(i = 0;i < num&&cjs == 0&&!feof(fp);i++) { cd[i] = ' '; cd[i+1] = '\0'; cd[i] = fgetc(fp); for(j = 1;j <= num;j++) { if(strcmp(HC[j].bits,cd) == 0) { str[k] = HC[j].ch; k++; cjs = 1; break; } } } } str[k] = '\0'; p = str; return p;}void main(){ char st[254],*s,str[27]; int cn[27]; HuffmanTree HT; HuffmanCode HC; printf("输入需要编码的字符串(假设均为大写字母):\n"); gets(st); num = jsq(st,cn,str); CreHuffmanTree(HT,HC,cn,str); HuffmanEncoding(HT,HC); coding(HC,st); s = decode(HC); printf("译码后的字符串:"); printf("%s\n",s);}
[解决办法]
Mark,瞌睡了,睡醒在看,我刚看懂哈夫曼……