信息论实习报告Word文件下载.docx

上传人:b****6 文档编号:17192075 上传时间:2022-11-28 格式:DOCX 页数:33 大小:782.48KB
下载 相关 举报
信息论实习报告Word文件下载.docx_第1页
第1页 / 共33页
信息论实习报告Word文件下载.docx_第2页
第2页 / 共33页
信息论实习报告Word文件下载.docx_第3页
第3页 / 共33页
信息论实习报告Word文件下载.docx_第4页
第4页 / 共33页
信息论实习报告Word文件下载.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

信息论实习报告Word文件下载.docx

《信息论实习报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《信息论实习报告Word文件下载.docx(33页珍藏版)》请在冰豆网上搜索。

信息论实习报告Word文件下载.docx

{

low=Low;

high=Low+chance[j]*d;

High=high;

d*=chance[j];

}

else

doublechance_l=0.0;

for(intk=0;

k<

=j-1;

k++)

chance_l+=chance[k];

low=Low+d*chance_l;

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

Low=low;

}

}

else

continue;

}

2)计算码长

for(inti=0;

for(intj=0;

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

sum*=chance[i];

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

3)求最终编码

for(inti=0;

L;

{

Low*=2;

if(Low>

1)

cout<

<

1;

Low-=1;

else

cout<

0;

7.3程序运行结果

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

输入符号序列:

得到相应的结果:

该数据来源为课件。

7.4、程序分析

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

重新认识了算术编码的编码过程,对于解码部分,并未做相应的编程实现。

但是了解了其解码过程,虽然对能否无损解码持怀疑态度。

八、源代码

#include<

iostream>

usingnamespacestd;

math.h>

#defineM100

#defineN4

classsuanshu

{

intcount,length;

charnumber[N],n;

longdoublechance[N],c;

charcode[M];

longdoubleHigh,Low,high,low,d;

public:

suanshu()

{High=0;

Low=0;

}

voidget_number();

voidget_code();

voidcoding();

voidprint();

~suanshu(){};

};

voidsuanshu:

:

get_number()

cout<

"

输入信源符号及其对应概率:

endl;

inti;

longdoublesum=0.00;

for(i=0;

N&

&

sum<

=1;

cin>

>

n>

c;

number[i]=n;

chance[i]=c;

sum+=c;

if(i==20)

cout<

信源符号数溢出."

if(sum>

概率和超过."

count=i;

get_code()

输入符号序列长:

;

cin>

length;

while(length>

=M)

输入的符号序列超长,请改小!

cin>

for(inti=0;

i<

i++)

code[i];

coding()

{

inti,j=0;

for(i=0;

count;

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

break;

while(j<

i)

Low+=chance[j++];

d=chance[j];

High=Low+d;

print()

算数编码结果为:

Low<

二进制结果:

doublesum=1.00;

for(inti=0;

for(inti=0;

voidmain()

suanshua;

a.get_number();

a.get_code();

a.coding();

a.print();

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

一、实验内容

根据信源压缩编码——Huffman编码的原理,制作对英文文本进行压缩和解压缩的软件。

要求软件有简单的用户界面,软件能够对运行的状态生成报告,分别是:

字符频率统计报告、编码报告、压缩程度信息报告、码表存储空间报告。

4.计算机

5.Windows2000或以上

6.MicrosoftOffice2000或以上

7.VS2005

3.掌握Huffman编码的原理

4.掌握VC开发环境的使用(尤其是程序调试技巧)

5.掌握C语言编程(尤其是位运算和文件的操作)

6.掌握数据结构的内容:

链表、顺序表、堆栈、最优二叉树

7.掌握结构化程序分析和开发的软件工程原理

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

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

6.认真填写实验报告。

压缩/解压缩流程

压缩流程:

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

解压缩流程:

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

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

3.《数据结构》,清华大学出版社

7.1数据结构描述:

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

//哈夫曼树结点结构体实现

typedefstructtalNode{

unsignedcharc;

//叶结点时对应ASCII值

intweight;

//该结点权值

intlt,rt;

//左、右结点下标

talNode(){}

talNode(unsignedchar_c,int_p):

c(_c),weight(_p),lt(-1),rt(-1)

{}

talNode(unsignedchar_c,int_p,intl,intr)

:

c(_c),weight(_p),lt(l),rt(r)

booloperator<

(talNodea)

{//重载运算符“<

”用于二叉堆内的比较

returnweight<

a.weight;

}HuffNode;

哈夫曼树以数组形式保存,其元素个数是2n-1,其中n为叶子数。

对应结点的哈夫曼编码用一个数组记录,该数组元素是指向字符的指针

7.2主要算法描述

7.2.1压缩

其基本实现方法是,因为英文文件中都是ACSII码(包括英文的标点符号),所以对选定的文件文本读入,一次读入一个字符,然后对每个ASCII字符进行统计,如此循换,这就统计出文件的每个字符的权值了。

得出文件各字节的权值后,就可以构造对应哈夫曼的哈夫曼树,从而就可以构造出对应字符的哈夫曼编码了。

每个字符的哈夫曼编码都知道了,那么文件的哈夫曼编码就可以求出了。

7.2.2关于解压

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

7.3具体函数设计

7.3.1压缩函数设计

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

SaveHuffHead(fpt);

//写入压缩文件的头信息!

!

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

l=data=0;

puts("

Encoding..."

);

//编码压缩过程,依次对源文件字符进行编码

while(true){//存入一个字符中,用移位操作实现,每位前

c=fgetc(fp);

//缀码对应一个字符,将该字符存入目标文件,

if(feof(fp))break;

//最终不足位的记录最后一位占用的前缀码长度

soucelen++;

//源文件长度增加

for(i=0;

lenth[c];

i++){//对data进行左移,空出最低位

data<

=1;

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

data+=code[c][i];

if(++l%8==0){//满位,则存储

fputc(data,fpt);

targetlen++;

//目标文件长度增加

}//对最后的一个字符进行处理

lastcodelenth=l%8;

//记录实际占用位的长度

data<

=8-lastcodelenth;

//空出剩余位

fputc(data,fpt);

//输出至文件

targetlen++;

//目标文件长度增加

该函数主要是涉及三个步骤:

构造哈夫曼树、构造哈弗曼编码、压缩。

7.3.2解压函数设计

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

DeCodePre(fp);

l=0;

Decoding..."

fscanf(fp,"

%c"

&

c);

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

//按位取出,存于tmp[]中,找出前缀码对应的字符

while(!

feof(fp)){

fscanf(fp,"

t);

if(feof(fp))break;

for(i=l+7;

i>

=l;

i--){//按位取出前缀码

tmp[i]=c&

1;

c>

}l+=8;

while(l>

=32){//如果当前前缀码段超出一定的长度,则取出前缀码进行解码

for(i=0,cur=arr[size-1];

cur.c;

cur=tmp[i]?

arr[cur.rt]:

arr[cur.lt];

//找到前缀码段对应第一个字符

fprintf(fpt,"

cur.c);

//输出至目标文件

l-=i;

targetlen++;

//前缀码段减去当前字符前缀码长度

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

//数组顺移至开头,即从开始记录当前的前缀码段

}c=t;

for(i=l+7;

i--){//对最后一个字符做特殊处理

tmp[i]=c&

//取出每一位

c>

l+=lastcodelenth;

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

while(l){//输出剩余的前缀码段对应的字符

for(i=0,cur=arr[size-1];

cur=tmp[i]?

fprintf(fpt,"

l-=i;

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

fclose(fp);

fclose(fpt);

//关闭文件

7.4程序体验

7.4.1程序界面:

7.4.2选择文件并压缩:

源文件“test.txt”的内容

选取文件

压缩完成

选择的源文件为:

“D:

\我的文档\test.txt”压缩后的文件存储在相同路径下,压缩后的文件名:

“test.huf”,文件长度减小了7908。

其内容为下:

压缩后的内容

7.4.3解压

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

解压成功

解压后的文件名为:

“test.txt”

解压后的文件内容

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

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

DE01E3358BCA716ACB444661E862CBDD

Huffman.h:

#pragmaonce

//***************************************************************

//课程:

信息论与编码

//题目:

霍夫曼编码实现文本压缩解压

//老师:

余林琛

//作者:

刘宇豪

//时间:

-11-2

#include<

stdlib.h>

#include"

stdafx.h"

#defineASCIIL256

#defineF(x)((x-1)>

1)

#defineL(x)((x<

1)+1)

#defineR(x)((x<

1)+2)

#defineSWAP(a,b,tmp){tmp=a;

a=b;

b=tmp;

//实现二叉堆模板类,小顶堆

template<

classHeapType>

classCHeap

HeapType*data,tmp;

intsize;

voidHeapUp(intix)

{//自底向顶维护堆

intf;

for(f=F(ix);

ix&

data[ix]<

data[f];

ix=f,f=F(f))

SWAP(data[ix],data[f],tmp);

voidHeapDown(intix)

{//自顶向底维护堆

intl,r,t;

HeapTypemin,tmp;

if(ix>

=size)return;

l=L(ix),r=R(ix);

min=data[ix],t=ix;

if(l<

size&

data[l]<

min)

t=l,min=data[l];

if(r<

data[r]<

t=r,min=data[l];

SWAP(data[ix],data[t],tmp);

if(ix!

=t)HeapDown(t);

CHeap()

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

size=0;

data=newHeapType[256];

~CHeap()

{//释放内存

deletedata;

intgetsize()

{//返回堆大小

returnsize;

voidclear()

{//清空堆

voidinsert(HeapTypee)

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

data[size++]=e;

HeapUp(size-1);

HeapTypetop()

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

HeapTyperet=data[0];

data[0]=data[--size];

HeapDown(0);

returnret;

classCHuffMan{

HuffNodearr[512];

//哈夫曼树结点数组

//哈夫曼树结点个数

boolcode[256][64];

//ASCII对应编码方案

intlenth[256];

//ASCII对应编码长度

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

intlastcodelenth;

//文件最后一个字符实用几位

intps[256];

//ASCII对应出现频率

intsoucelen,targetlen;

//源及目标文件长度

//私有成员函数,用于实现内部功能

voidSetHuffTree(int[]);

//根据字符频率生成哈夫曼树

voidSetHuffCode(int,bool[],int);

//根据哈夫曼树生成编码方案

voidCreateHuff(int[]);

//创建哈夫曼树及编码方案

voidEnCodePre(CString);

//压缩前预处理

voidDeCodePre(FILE*);

//解压前预处理

voidSaveHuffHead(FILE*);

//保存压缩文件头

voidReadHuffHead(FILE*);

//读取压缩文件头

CHuffMan(){Clear();

}//构造函数

~CHuffMan(){}//析构函数

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

voidClear();

//清空当前对象内容

voidEnCodeFile(CString,CString);

//编码,用于压缩文件,第一个参数为源文件名,第二个参数为目标文件名

voidDeCodeFile(CString,CString);

//解码

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1