您的当前位置:首页正文

信息论实习报告

2024-08-05 来源:易榕旅网
实验三 算术编码

一、 实验内容

编程实现算术编码算法 二、实验环境

1. 计算机

2. Windows 2000 或以上 3. VS2005 三、实验目的

1. 进一步熟悉算术编码算法; 2. 掌握C语言编程(尤其是数值的进制转换,数值与字符串之间的转换等) 四、实验要求

1. 提前预习实验,认真阅读实验原理。

2. 认真高效的完成实验,实验过程中服从实验室管理人员以及实验指导老

师的管理。

3. 认真填写实验报告。 五、实验原理

算术编码是把一个信源表示为实轴上0和1之间的一个区间,信源集合中的每一个元素都用来缩短这个区间。

1. 算法流程

(1) 输入信源符号个数,信源概率分布,还有需要编码的符号序列, (2) 根据概率可以算出初始编码间隔, High——当前编码的上限, Low——当前编码的下限, high——中间变量,用来计算下一个编码符号的当前间隔的上限, low——中间变量,用来计算下一个编码符号的当前间隔的下限, d——当前间隔之间的距离。 (3)扫描需编码的符号序列,确定编码空间 第1个编码符号的当前间隔为其初始的编码间隔, 第i个编码符号的当前间隔为第i-1个编码后的[Low,High), 第i+1个编码符号的当前间隔算法如下:high=Low+d*第i+1个初始编码符号对应的上限,low=Low+d*第i+1个编码符号对应的下限,然后High=high,Low=low,d=d*第i个编码符号的概率。 六、参考书

1. 《信息论——基础理论及应用》傅祖芸,电子工业出版社

七、程序设计 7.1程序流程图

开始 输入信源符号及其概率 求出信源符号的累加概率 根据信源符号的概率和累加概率对待编码序列进行算术编码,并输出

7.2关键代码设计

1)计算部分最终得到Low

for(i = 1;i < length;i++) for(j = 0;j < count;j++) {

if(code[i] == number[j]) {

if(j == 0) { } else { }

double chance_l = 0.0; for(int k = 0;k <= j-1;k++)

chance_l += chance[k]; low = Low + d * chance_l;

high = Low + d * (chance_l + chance[j]); Low = low; High = high; d *= chance[j];

low = Low;

high = Low + chance[j] * d; High = high; d *= chance[j];

}

} else

continue;

2)计算码长

for (int i = 0;i < length;i++)

for (int j = 0;j < count;j++) { }

if (code[i] == number[j])

sum *= chance[i];

int L = (int) log(1.00/sum);

3)求最终编码

for(int i = 0;i < L;i++)

{ }

Low *= 2; if (Low > 1) { } else

cout<<0; cout << 1; Low -= 1;

7.3程序运行结果

输入信源符号及对应的概率分布:

输入符号序列:

得到相应的结果:

该数据来源为课件。 7.4、程序分析

在网上下的程序并未对码长以及最终编码进行计算和输出,根据可见所讲,将信息熵求出后计算了码长,并输出了最后的编码结果。

重新认识了算术编码的编码过程,对于解码部分,并未做相应的编程实现。但是了解了其解码过程,虽然对能否无损解码持怀疑态度。 八、源代码

#include using namespace std; #include #define M 100 #define N 4 class suanshu { };

void suanshu::get_number() {

cout<<\"输入信源符号及其对应概率:\"<long double sum = 0.00;

for(i = 0;i < N && sum <= 1;i++) int count,length; char number[N],n;

long double chance[N],c; char code[M];

long double High,Low,high,low,d; suanshu() {High=0;Low=0;} void get_number(); void get_code(); void coding(); void print(); ~suanshu(){};

public:

}

{ }

if(i == 20)

cout<<\"信源符号数溢出.\"< 1) count = i;

cin >> n >> c; number[i] = n; chance[i] = c; sum += c;

void suanshu::get_code() { }

void suanshu::coding() {

int i,j=0;

for(i=0;ibreak; while(jLow += chance[j++]; d = chance[j]; High = Low + d;

for(i = 1;i < length;i++) for(j = 0;j < count;j++) {

if(code[i] == number[j]) {

if(j == 0) {

low = Low;

high = Low + chance[j] * d;

cout<<\"输入符号序列长:\"; cin>>length; while(length>=M) { }

for(int i=0;icin>>code[i];

cout<<\"输入的符号序列超长,请改小!\"; cin>>length;

}

}

}

}

High = high; d *= chance[j];

else { }

double chance_l = 0.0; for(int k = 0;k <= j-1;k++)

chance_l += chance[k]; low = Low + d * chance_l;

high = Low + d * (chance_l + chance[j]); Low = low; High = high; d *= chance[j];

else

continue;

void suanshu::print() {

cout<<\"算数编码结果为:\"<for (int i = 0;i < length;i++)

for (int j = 0;j < count;j++) { }

if (code[i] == number[j])

sum *= chance[i];

int L = (int) log(1.00/sum); for(int i = 0;i < L;i++) { }

cout<Low *= 2; if (Low > 1) { } else

cout<<0; cout << 1; Low -= 1;

}

void main() { }

suanshu a; a.get_number(); a.get_code(); a.coding(); a.print();

实验四 Huffman编码对英文文本的压缩和解压缩

一、实验内容

根据信源压缩编码——Huffman编码的原理,制作对英文文本进行压缩和解压缩的软件。要求软件有简单的用户界面,软件能够对运行的状态生成报告,分别是:字符频率统计报告、编码报告、压缩程度信息报告、码表存储空间报告。 二、实验环境

4. 计算机

5. Windows 2000 或以上 6. Microsoft Office 2000 或以上 7. VS2005 三、实验目的

3. 掌握Huffman编码的原理

4. 掌握VC开发环境的使用(尤其是程序调试技巧) 5. 掌握C语言编程(尤其是位运算和文件的操作) 6. 掌握数据结构的内容:链表、顺序表、堆栈、最优二叉树 7. 掌握结构化程序分析和开发的软件工程原理 四、实验要求

4. 提前预习实验,认真阅读实验原理。

5. 认真高效的完成实验,实验过程中服从实验室管理人员以及实验指导老

师的管理。 6. 认真填写实验报告。 五、实验原理

压缩/解压缩流程

压缩流程:

读取扫描文本文件——〉统计字符频率——〉生成码字——〉保存压缩文件 解压缩流程:

读取扫描压缩文件——〉提取字符频率——〉生成码树——〉保存文本文件 六、参考书

1. 《信息论——基础理论及应用》傅祖芸,电子工业出版社 2. 《数据结构》,清华大学出版社

七、程序设计

7.1数据结构描述:

以下是哈夫曼树结点的结构:

哈夫曼树以数组形式保存,其元素个数是2n-1,其中n为叶子数。typedef struct talNode{ 对应结点的哈夫曼编码用一个数组 unsigned char c; //叶结点时对应ASCII记录,该数组元素是指向字符的指值 针 int weight; //该结点权值 7.2主要算法描述 int lt,rt; //左、右结点下标 7.2.1压缩 talNode(){} 其基本实现方法是,因为英文 talNode(unsigned char _c,int _p): 文件中都是ACSII码(包括英文的 c(_c),weight(_p),lt(-1),rt(-1) 标点符号),所以对选定的文件文本 {} 读入,一次读入一个字符,然后对 talNode(unsigned char _c,int _p,int 每个ASCII字符进行统计,如此循l,int r) 换,这就统计出文件的每个字符的 :c(_c),weight(_p),lt(l),rt(r) 权值了。 {} 得出文件各字节的权值后,就 bool operator < (talNode a) 可以构造对应哈夫曼的哈夫曼树, {//重载运算符“<”用于二叉堆内的比较 从而就可以构造出对应字符的哈夫 return weight7.2.2关于解压

解压时,先读出哈夫曼编码的节点及其权值,然后对编码部分读取一个字节(8 bit)用一个函数转换为8个字符(用一个数组记录,其元素只是一个0或一个1),然后按哈夫曼树从顶向下查找,如果到达叶子结点,就读出该叶子结点的值,放入缓冲区中,如果不是,则继续找,如此重复,直到缓冲区满了,就写入到解压文件中,再循环以上过程,直到处理完所有数据。 7.3具体函数设计 7.3.1压缩函数设计

点击压缩后,调用压缩函数EnCodeFile()

//哈夫曼树结点结构体实现 SaveHuffHead(fpt);

l=data=0;

puts(\"Encoding ... \");

//编码压缩过程,依次对源文件字符进行编码 while(true){

//存入一个字符中,用移位操作实现,每位前 //缀码对应一个字符,将该字符存入目标文件,

//最终不足位的记录最后一位占用的前缀//源文件长度增加

//对当前字符的前缀码当前们存储于data

c=fgetc(fp);

//写入压缩文件的头信息!!!注意,此时

lastcodelenth为空,需压缩结束时重置

if(feof(fp)) break; soucelen++;

data<<=1;

码长度

for(i=0;i//对data进行左移,空出最低位

}

}

//对最后的一个字符进行处理 //记录实际占用位的长度 //空出剩余位

data+=code[c][i]; if(++l%8==0){ }

//满位,则存储

fputc(data,fpt); targetlen++;

//目标文件长度增加

lastcodelenth=l%8; fputc(data,fpt); targetlen++;

data<<=8-lastcodelenth;

//输出至文件 //目标文件长度增加

该函数主要是涉及三个步骤:构造哈夫曼树、构造哈弗曼编码、压缩。 7.3.2解压函数设计

点击解压后,调用解压函数DeCodeFile() DeCodePre(fp);

}

for(i=l+7;i>=l;i--){

tmp[i]=c&1; c>>=1;

//对最后一个字符做特殊处理

//取出每一位

while(l>=32){

//如果当前前缀码段超出一定的长度,则

取出前缀码进行解码

for(i=0,cur=arr[size-1];!cur.c;i++)

cur=tmp[i]?arr[cur.rt]:arr[cur.lt];//找到前缀码段对应第一个字符

//输出至目标文件

//前缀码段减去当前字符前缀码//数组顺移至开头,即从开始记

fprintf(fpt,\"%c\",cur.c); l-=i;targetlen++;

for(i=l+7;i>=l;i--){

tmp[i]=c&1;c>>=1; }l+=8;

//按位取出前缀码

l=0;

//解码过程,压缩过程的逆过程,取出编

puts(\"Decoding ... \"); fscanf(fp,\"%c\",&c);

码了的字符,

//按位取出,存于tmp[]中,找出前缀码对应的字符 while(!feof(fp)){

soucelen++;

fscanf(fp,\"%c\",&t); if(feof(fp))break;

长度

memmove(tmp,tmp+i,sizeof(bool)*l);

录当前的前缀码段

}c=t;

}

l+=lastcodelenth; while(l){ }

fclose(fp);fclose(fpt);

//关闭文件

//只利用最后一个字符的前//输出剩余的前缀码段对应的字

lastcodelenth位

for(i=0,cur=arr[size-1];!cur.c;i++)

cur=tmp[i]?arr[cur.rt]:arr[cur.lt]; fprintf(fpt,\"%c\",cur.c);l-=i;targetlen++; memmove(tmp,tmp+i,sizeof(bool)*l);

7.4程序体验 7.4.1程序界面:

7.4.2选择文件并压缩:

源文件“test.txt”的内容

选取文件

压缩完成

选择的源文件为:“D:\\我的文档\est.txt”压缩后的文件存储在相同路径

下,压缩后的文件名:“test.huf”,文件长度减小了7908。其内容为下:

压缩后的内容

7.4.3解压

选择刚才的压缩文件进行解压:

选取文件

解压成功

解压后的文件名为:“test.txt”

解压后的文件内容 经过压缩解压后得到的文件内容和压缩前的一致。

利用MD5比较,得到压缩前文件与解压得到的文件为同一文件。

DE01E3358BCA716ACB444661E862CBDD DE01E3358BCA716ACB444661E862CBDD

八、源代码 Huffman.h:

#pragma once

//*************************************************************** //课程:信息论与编码

//题目:霍夫曼编码实现文本压缩解压

//老师:余林琛 //作者:刘宇豪 //时间:-11-2

//*************************************************************** #include #include #include \"stdafx.h\" #define ASCIIL 256 #define F(x) ((x-1)>>1) #define L(x) ((x<<1)+1) #define R(x) ((x<<1)+2)

#define SWAP(a,b,tmp) {tmp=a;a=b;b=tmp;} using namespace std; //实现二叉堆模板类,小顶堆 template class CHeap {

HeapType *data,tmp; int size;

void HeapUp(int ix) {//自底向顶维护堆 }

void HeapDown(int ix) {//自顶向底维护堆 } CHeap()

{//这里特殊应用,堆内元素个数不超过

size=0;

data=new HeapType[256]; int l,r,t; HeapType min,tmp; if(ix>=size) return ; l=L(ix),r=R(ix); min=data[ix],t=ix; if(lt=l,min=data[l]; t=r,min=data[l]; if(rfor(f=F(ix);ix&&data[ix]SWAP(data[ix],data[f],tmp);

public:

};

} ~CHeap() {//释放内存 }

int getsize() {//返回堆大小 }

void clear() {//清空堆 }

void insert(HeapType e)

{//向堆尾中插入元素,并向顶维护堆 }

HeapType top()

{//从堆顶取出元素,并向底维护堆 }

HeapType ret=data[0]; data[0]=data[--size]; HeapDown(0);return ret; data[size++]=e; HeapUp(size-1); size=0; return size; delete data;

//哈夫曼树结点结构体实现 typedef struct talNode{

unsigned char c; //叶结点时对应ASCII值 int weight; int lt,rt; talNode(){}

talNode(unsigned char _c,int _p): c(_c),weight(_p),lt(-1),rt(-1) {}

talNode(unsigned char _c,int _p,int l,int r) {}

bool operator < (talNode a) {//重载运算符“<”用于二叉堆内的比较 }

return weight//该结点权值 //左、右结点下标

}HuffNode; class CHuffMan{

HuffNode arr[512];

//哈夫曼树结点数组

};

int size;

//哈夫曼树结点个数 //ASCII对应编码方案 //ASCII对应编码长度 //文件最后一个字符实用几位

bool code[256][64]; int lenth[256]; int lastcodelenth; int ps[256];

//lastcodelenth,ps[256],用于存储压缩文件中作为文件头

//ASCII对应出现频率

int soucelen,targetlen; //源及目标文件长度 //私有成员函数,用于实现内部功能 void SetHuffTree(int []); void CreateHuff(int []); void EnCodePre(CString); void DeCodePre(FILE *); void SaveHuffHead(FILE *); void ReadHuffHead(FILE *); CHuffMan(){Clear();} ~CHuffMan(){} void Clear();

//根据字符频率生成哈夫曼树 //创建哈夫曼树及编码方案 //压缩前预处理

//解压前预处理 //保存压缩文件头 //读取压缩文件头

void SetHuffCode(int ,bool [],int );//根据哈夫曼树生成编码方案

public:

//构造函数

//析构函数

//清空当前对象内容

//公有成员函数,用于提供使用接口

void EnCodeFile(CString,CString); //编码,用于压缩文件,第一个参数为源文件名,第void DeCodeFile(CString,CString); //解码,用于解压文件,第一个参数为源文件名,第int GetSouceLen();

//输出当前工作项的源文件长度 //输出当前工作项的目标文件长度

二个参数为目标文件名 二个参数为目标文件名

int GetTargetLen();

void CHuffMan::SetHuffTree(int ps[]) {

//每次取出两权值最小的结点合并成新树, //加入堆,直至堆中只余有一个元素 CHeap hp; } size=0; }

//初始化哈夫曼树中结点个数 //取出权值最小的两个结点

while(hp.getsize()>1){

arr[size++]=hp.top(); arr[size++]=hp.top(); hp.insert(HuffNode(0,

arr[size-1].weight+arr[size-2].weight, size-1,size-2));

//合并结点,并插入堆

if(ps[i])

hp.insert(HuffNode(i,ps[i]));

//二叉堆对象

//如果字符i出现过,则插入二插堆

for(int i=0;i}

arr[size++]=hp.top(); //arr[size-1]为哈夫曼树根

void CHuffMan::SetHuffCode(int ix,bool stk[],int top) { }

void CHuffMan::CreateHuff(int ps[]) { }

void CHuffMan::EnCodePre(CString sfilename) {

//压缩文件预处理,读取字符出现频率 //及构造哈夫曼树及前缀码

FILE *fp; int c;

char *file_tmp;

DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,sfilename,-1,NULL,0,NULL,FALSE); file_tmp = new char[dwNum];

WideCharToMultiByte(CP_OEMCP,NULL,sfilename,-1,file_tmp,dwNum,NULL,FALSE); fp=fopen(file_tmp,\"rb\"); if(fp==NULL){

if(MessageBox(NULL,L\"打开文件出错\",L\"梦已喂马\",MB_OK)) }

memset(ps,0,sizeof(ps)); while(true){ }

fclose(fp);

c=fgetc(fp); if(feof(fp))break; ps[c]++;

//读取字符出现频率

exit(0);

//构造哈夫曼树及前缀码

bool stk[64]; SetHuffTree(ps);

//根据字符频率构造哈夫曼树

//根据哈夫曼树生成前缀码

SetHuffCode(size-1,stk,0);

//递归深搜哈夫曼树,生成所有存在的ASCII的//如果

前缀码

if(arr[ix].c){ }

stk[top]=0; stk[top]=1;

//左子树的边设为 //递归进入左子树 //右子树的边设为 //递归进入右子树

SetHuffCode(arr[ix].lt,stk,top+1); SetHuffCode(arr[ix].rt,stk,top+1);

if(top){ }

else lenth[arr[ix].c]=1; return ;

//此判断用于只含有一类字符的文件

memmove(code[arr[ix].c],stk,sizeof(bool)*top); lenth[arr[ix].c]=top;

}

CreateHuff(ps); //构造哈夫曼树及前缀码

void CHuffMan::DeCodePre(FILE *fp) { }

void CHuffMan::SaveHuffHead(FILE *fp) { }

void CHuffMan::ReadHuffHead(FILE *fp) { }

void CHuffMan::Clear() { }

int CHuffMan::GetSouceLen() { }

int CHuffMan::GetTargetLen() { }

void CHuffMan::EnCodeFile(CString sfilename,CString gfilename) {

//将文件sfilename压缩为文件gfilename FILE *fp,*fpt; int c,data,l,i; char *file_tmp;

file_tmp = new char[sfilename.GetLength() + 1];

DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,sfilename,-1,NULL,0,NULL,FALSE);

//获取当前工作项的目标文件长度

return targetlen;

//获取当前工作项的源文件长度

return soucelen;

//清空前前工作项

size=0;soucelen=targetlen=0; lastcodelenth=0;

memset(lenth,0,sizeof(lenth)); memset(ps,0,sizeof(ps));

//从缩文件中读文件头

//从lastcodelenth的地址开始的连续

fread((void *)&lastcodelenth,4,257,fp); //4*257个字节,即lastcodelenth和 soucelen+=4*257;

//ps[256]数组内容

//向压缩文件中写文件头

fwrite((void *)&lastcodelenth,4,257,fp);//从lastcodelenth的地址开始的连续 //4*257个字节,即lastcodelenth和 //ps[256]数组内容 targetlen+=4*257;

//解压文件预处理,读取压缩文件头

//根据读取头信息构千哈夫曼树及前缀码 ReadHuffHead(fp); CreateHuff(ps);

中 至 }

file_tmp = new char[dwNum];

WideCharToMultiByte (CP_OEMCP,NULL,sfilename,-1,file_tmp,dwNum,NULL,FALSE); EnCodePre(sfilename); fp=fopen(file_tmp,\"rb\"); if(fp==NULL){ }

delete [] file_tmp;

dwNum = WideCharToMultiByte(CP_OEMCP,NULL,gfilename,-1,NULL,0,NULL,FALSE); file_tmp= new char[dwNum];

WideCharToMultiByte (CP_OEMCP,NULL,gfilename,-1,file_tmp,dwNum,NULL,FALSE); fpt=fopen(file_tmp,\"wb\"); SaveHuffHead(fpt); l=data=0;

puts(\"Encoding ... \");

//编码压缩过程,依次对源文件字符进行编码 while(true){ }

//满位,则存储

//存入一个字符中,用移位操作实现,每位前 //缀码对应一个字符,将该字符存入目标文件,

//最终不足位的记录最后一位占用的前缀//源文件长度增加

//对当前字符的前缀码当前们存储于data

c=fgetc(fp);

//写入压缩文件的头信息!!!注意,此时

if(MessageBox(NULL,L\"打开文件出错\",L\"梦已喂马\",MB_OK))

exit(0);

//压缩预处理,生成哈曼树及字符前缀码

lastcodelenth为空,需压缩结束时重置

if(feof(fp)) break; soucelen++; }

data<<=1;

码长度

for(i=0;i//对data进行左移,空出最低位

data+=code[c][i]; if(++l%8==0){ }

fputc(data,fpt); targetlen++;

//目标文件长度增加

//对最后的一个字符进行处理 //记录实际占用位的长度 //空出剩余位

lastcodelenth=l%8; fputc(data,fpt); targetlen++;

data<<=8-lastcodelenth;

//输出至文件 //目标文件长度增加

//!!!回溯至文件头,更新lastcodelenth//真实值 //关闭文件

fseek(fpt,0,SEEK_SET);

fwrite(&lastcodelenth,4,1,fpt); fclose(fp); fclose(fpt);

void CHuffMan::DeCodeFile(CString sfilename,CString gfilename)

{

//解压文件sfile至gfile

FILE *fp,*fpt; char *file_tmp;

DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,sfilename,-1,NULL,0,NULL,FALSE); file_tmp = new char[dwNum];

WideCharToMultiByte(CP_OEMCP,NULL,sfilename,-1,file_tmp,dwNum,NULL,FALSE); fp=fopen(file_tmp,\"rb\"); delete []file_tmp;

dwNum = WideCharToMultiByte(CP_OEMCP,NULL,gfilename,-1,NULL,0,NULL,FALSE); file_tmp = new char[dwNum];

WideCharToMultiByte(CP_OEMCP,NULL,gfilename,-1,file_tmp,dwNum,NULL,FALSE); fpt=fopen(file_tmp,\"wb\"); int c,t,l,i; HuffNode cur; bool tmp[64]; DeCodePre(fp); l=0;

//解码过程,压缩过程的逆过程,取出编

puts(\"Decoding ... \"); fscanf(fp,\"%c\",&c);

//tmp[]用于记录当前的前缀码段

//l用于记录当前前缀码段的长度

码了的字符,

//按位取出,存于tmp[]中,找出前缀码对应的字符 while(!feof(fp)){ }

for(i=l+7;i>=l;i--){ }

l+=lastcodelenth;

//只利用最后一个字符的前

tmp[i]=c&1; c>>=1;

//对最后一个字符做特殊处理

//取出每一位

soucelen++;

fscanf(fp,\"%c\",&t); if(feof(fp))break; for(i=l+7;i>=l;i--){

tmp[i]=c&1;c>>=1;

//如果当前前缀码段超出一定的长度,则

}l+=8; while(l>=32){

//按位取出前缀码

取出前缀码进行解码

for(i=0,cur=arr[size-1];!cur.c;i++)

cur=tmp[i]?arr[cur.rt]:arr[cur.lt];//找到前缀码段对应第一个字符

//输出至目标文件

//前缀码段减去当前字符前缀码//数组顺移至开头,即从开始记

fprintf(fpt,\"%c\",cur.c); l-=i;targetlen++;

长度

memmove(tmp,tmp+i,sizeof(bool)*l);

录当前的前缀码段

}c=t;

lastcodelenth位 符 }

test_MFCDlg.cpp:

// test_MFCDlg.cpp : 实现文件 //

#include \"stdafx.h\" #include \"test_MFC.h\" #include \"test_MFCDlg.h\" #include \"Huffman.h\" #ifdef _DEBUG

#define new DEBUG_NEW #endif

// Ctest_MFCDlg 对话框

Ctest_MFCDlg::Ctest_MFCDlg(CWnd* pParent /*=NULL*/) { }

void Ctest_MFCDlg::DoDataExchange(CDataExchange* pDX) { }

BEGIN_MESSAGE_MAP(Ctest_MFCDlg, CDialog)

ON_WM_PAINT()

ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP

ON_BN_CLICKED(IDC_ChBtn, &Ctest_MFCDlg::OnBnClickedChbtn) ON_BN_CLICKED(IDC_Unzip, &Ctest_MFCDlg::OnBnClickedUnzip) CDialog::DoDataExchange(pDX);

DDX_Control(pDX, IDC_FileEdit, f_edit); DDX_Control(pDX, IDC_Show, s_edit);

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); : CDialog(Ctest_MFCDlg::IDD, pParent) }

fclose(fp);fclose(fpt);

//关闭文件

for(i=0,cur=arr[size-1];!cur.c;i++)

cur=tmp[i]?arr[cur.rt]:arr[cur.lt]; fprintf(fpt,\"%c\",cur.c);l-=i;targetlen++; memmove(tmp,tmp+i,sizeof(bool)*l); while(l){

//输出剩余的前缀码段对应的字

END_MESSAGE_MAP()

// Ctest_MFCDlg 消息处理程序 BOOL Ctest_MFCDlg::OnInitDialog() {

CDialog::OnInitDialog();

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动

}

// 执行此操作

SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE);

// 设置大图标 // 设置小图标

// TODO: 在此添加额外的初始化代码

return TRUE; // 除非将焦点设置到控件,否则返回TRUE

// 如果向对话框添加最小化按钮,则需要下面的代码

// 来绘制该图标。对于使用文档/视图模型的MFC 应用程序, // 这将由框架自动完成。 void Ctest_MFCDlg::OnPaint() { 0); }

//当用户拖动最小化窗口时系统调用此函数取得光标显示。 //

HCURSOR Ctest_MFCDlg::OnQueryDragIcon() { }

void Ctest_MFCDlg::OnBnClickedChbtn() {

// TODO: 在此添加控件通知处理程序代码 CHuffMan work;

CFileDialog filedlg(true);

filedlg.m_ofn.lpstrTitle=L\"Huffman压缩文件打开框\";

filedlg.m_ofn.lpstrFilter=L\"Text Files(*.txt)\\0*.txt\\0All Files(*.*)\\0*.*\\0\\0\"; return static_cast(m_hIcon); } else { }

CDialog::OnPaint(); // 使图标在工作矩形中居中

int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标

dc.DrawIcon(x, y, m_hIcon); if (IsIconic()) {

CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()),

}

if(IDCANCEL == filedlg.DoModal()) { }

CString str = filedlg.GetPathName(); f_edit.SetSel(0,-1); f_edit.ReplaceSel(str); int pos = str.Find(L\".\");

CString str_tmp = str.Left(pos + 1); str_tmp += L\"huf\"; work.Clear();

work.EnCodeFile(str,str_tmp); str_tmp = L\"\";

str_tmp.Format(_T(\"源文件长度:\%d 目标文件长s_edit.SetSel(0,-1); s_edit.ReplaceSel(str_tmp);

return;

度:\%d\"),work.GetSouceLen(),work.GetTargetLen());

void Ctest_MFCDlg::OnBnClickedUnzip() { }

// TODO: 在此添加控件通知处理程序代码 CHuffMan work;

CFileDialog filedlg(true);

filedlg.m_ofn.lpstrTitle=L\"Huffman解压文件打开框\";

filedlg.m_ofn.lpstrFilter=L\"Text Files(*.huf)\\0*.huf\\0All Files(*.*)\\0*.*\\0\\0\"; if(IDCANCEL == filedlg.DoModal()) { }

CString str = filedlg.GetPathName(); f_edit.SetSel(0,-1); f_edit.ReplaceSel(str); int pos = str.Find(L\".\");

CString str_tmp = str.Left(pos + 1); str_tmp += L\"txt\"; work.Clear();

work.DeCodeFile(str,str_tmp); str_tmp = L\"\";

str_tmp.Format(_T(\"源文件长度:\%d 目标文件长s_edit.SetSel(0,-1); s_edit.ReplaceSel(str_tmp);

return;

度:\%d\"),work.GetSouceLen(),work.GetTargetLen());

因篇幅问题不能全部显示,请点此查看更多更全内容