给定已压缩文件,怎样用霍夫曼解码从已压缩文件中解码?

ghost0129 2010-09-15 04:50:54
我是初学者,我需要步骤,听说是需要在源代码中加上待解压文件的地址,和文件名。但我不知道在哪加,怎么加。请高手帮帮忙。 有不明白我再补充,谢谢了。

// huff_C_exp.cpp : Defines the entry point for the console application.
//
#include"stdio.h"
#include "stdlib.h" //exit
#include "math.h" //pow,floor函数
#include "string.h" //strcmp函数

#define END_OF_STREAM 256 //最后结束符为257
#define Max_code_length 256 //共257个字符,可能的最长代码二进制位数为256个,假设第257个字符为结束符
#define Max_number 257 //加上结束符,共257个字符


typedef struct tree_node
{
//int data; //结点值
double weight; //权重,把权重写入输出文件时,
int flag; //标识是否为待构建结点,是的话用0表示,否则用1表示
int parent; //父结点
int Lchild; //左结点
int Rchild; //右结点
}NODE;

typedef struct codetype
{
int code[Max_code_length];

int code_length;//编码长度
}CODE;


FILE * read_file1(char*p);
FILE * write_file1(char*p);
void InitHuffman1(NODE nodes[],int n);
int build_tree1(NODE nodes[]);
void input_counts(FILE *input,NODE nodes[]);
void expand_data(FILE *input,FILE *output,NODE nodes[],int root_node);
int InputBit(FILE *input,unsigned char *pmask,int *pcode);



int main(int argc, char* argv[])
{

FILE *input,*output; //输入输出函数
NODE nodes[2*Max_number-1];//267个叶子节点
int root_node;//根节点
printf("\n decoding %s to %s\n",argv[1],argv[2]);
input=read_file1(argv[1]);//打开原始文件,读文件
output=write_file1(argv[2]); //打开新文件,写文件
InitHuffman1(nodes,Max_number);//初始化HUFFMAN树节点
input_counts(input,nodes); //从已压缩文件中读出每个字符的权值
root_node=build_tree1(nodes);//构建HUFFMAN树,返回根节点
expand_data(input,output,nodes,root_node);//从已压缩文件中解码

printf("decode finish\n");
return 0;
}






FILE * read_file1(char*p)
{
FILE * fp;
fp=fopen(p,"rb");//打开压缩文件
return (fp);
}

FILE * write_file1(char*p)
{FILE*fp;
fp=fopen(p,"wb");//创建解压后文件
return(fp);
}


void InitHuffman1(NODE nodes[],int n)//初始化节点数组
{
int i;
for (i=0; i<=2*n-2; i++)
{
nodes[i].flag=0;
nodes[i].parent=0;
nodes[i].weight=0;
nodes[i].Lchild=-1;
nodes[i].Rchild=-1;
}
}



int build_tree1(NODE nodes[])//建立huffman树
{
int i,a,b,k=1;
double az,bz;
while(k<=257)
{
for(i=0;i<513;i++)
if(nodes[i].weight!=0&&nodes[i].flag==0)
{
a=i;
az=nodes[i].weight;
break;
}//找初值
for(i=1;a+i<513;i++)
if(nodes[a+i].weight!=0&&nodes[a+i].flag==0)
if(az>nodes[a+i].weight)
{
az=nodes[a+i].weight;
a=a+i;
i=0;
}//找出最小值
nodes[a].flag=1;
for(i=0;i<513;i++)
if(nodes[i].weight!=0&&nodes[i].flag==0)
{
b=i;
bz=nodes[i].weight;
break;
}//找初值
if(i==513)
break;
for(i=1;b+i<513;i++)
if(nodes[b+i].weight!=0&&nodes[b+i].flag==0)
if(bz>nodes[b+i].weight)
{
bz=nodes[b+i].weight;
b=b+i;
i=0;
}//找出次最小值
nodes[b].flag=1;
nodes[256+k].Lchild=a;//左子树为最小值
nodes[256+k].Rchild=b;//右子树为次最小值
nodes[256+k].weight=az+bz;
nodes[a].parent=256+k;//双亲位置
nodes[b].parent=256+k;
k++;
}
return(a);//返回根节点
}


void input_counts(FILE *input,NODE nodes[])//取出压缩文件中各字符的权值
{
int i;
for(i=0;i<=256;i++)
nodes[i].weight=(double)fgetc(input);
}


void expand_data(FILE *input,FILE *output,NODE nodes[],int root_node)
{
int node,i;
unsigned char mask=0x80;
int ascii_code=0;
ascii_code=fgetc(input);//取字符
while(1)
{
node=root_node;
while(node>256)
{
i=InputBit(input,&mask,&ascii_code);//返回读入字符的每一位
if (i==0)
node=nodes[node].Lchild;//位值为0,node等于它的左子树
else
node=nodes[node].Rchild;

}
if(node==256)//判断是否为文件结尾
{
fclose(input);//关闭压缩文件
fclose(output);//关闭输出文件
break;
}
else
fputc(node,output);//非结尾写入输出文件
}


}

int InputBit(FILE *input,unsigned char *pmask,int *pcode)
{
int value;
value= (*pcode) & (*pmask);//判断位值
(*pmask)=(*pmask)>>1;//右移
if(*pmask==0)//一个字符结束开始下一个字符
{
*pmask=0x80;
*pcode=(int)fgetc(input);
}

return (value);//返回值
}
...全文
102 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
ghost0129 2010-09-21
  • 打赏
  • 举报
回复
应该是霍夫曼压缩的。我有源代码,但是不知道怎样应用才能将其解压出来。貌似是要加什么地址之类的。
hastings 2010-09-18
  • 打赏
  • 举报
回复
http://www.longen.com/E-K/detaile-k/HuffmanCode.htm
http://www.cnblogs.com/hoodlum1980/archive/2010/02/06/1665112.html
我看了这两个网页后了解了很多~~
第二个链接有源码~~不过有点小错误~~但是他的源码比较易懂~~
hastings 2010-09-18
  • 打赏
  • 举报
回复
给定已压缩文件,这压缩文件是别人压的?你需要知道压缩文件格式,及是不是Huffman压缩的。
fgsdcfgfsddfc 2010-09-18
  • 打赏
  • 举报
回复
貌似很困难。。。看不明白。。本人太菜了。。。- -!
vnking 2010-09-17
  • 打赏
  • 举报
回复
用XZip处理比较方便。

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧