ImageVerifierCode 换一换
格式:DOCX , 页数:28 ,大小:144.99KB ,
资源ID:23995519      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/23995519.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(实验2编码相关实验实验报告.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

实验2编码相关实验实验报告.docx

1、实验2编码相关实验实验报告信息论与编码实验二实验报告学生姓名 周群创 指导教师 张祖平 学 号 0909110814 专业班级 电子信息1101 一、实验目的1. 掌握香农码和 Huffman 编码原理和过程。2. 熟悉 matlab 软件的基本操作,练习使用matlab 实现香农码和Huffman编码。3. 熟悉 C/C+语言,练习使用C/C+实现香农码和Huffman 编码。4. 应用 Huffman 编码实现文件的压缩和解压缩。二、 实验原理 香农编码:香农第一定理指出了平均码长与信源之间的关系,同时也指出了可以通过编码使平均码长达到极限值,这是一个很重要的极限定理。如何构造这种码?香农

2、第一定理指出,选择每个码字的长度Ki满足下式 I(xi)KI(xi)+1, 就可以得到这种码。这种编码方法就是香农编码。香农第一定理:设离散无记忆信源为S P=s1 s2 .sq p(s1) p(s2) .p(sq) 熵为H(S),其N 次扩展信源为熵为H(SN)。码符号集X=(x1,x2,xr)。先对信源S N 进行编码,总可以找到一种编码方法,构成惟一可以码,使S 中每个信源符号所需的平均码长满足:当N时L 是平均码长 是ai 对应的码字长度哈夫曼编码:要完成哈夫曼的编码和解码需要首先建立哈夫曼树,之后对所有字符根据权重进行编码,最后再对文件内容进行编码和解码。首先定义适合哈夫曼树的节点类

3、型,需要定义的有当前节点的字符,当前节点的左子、右子和父亲指针。在建立哈夫曼树之前还需要对出现的字符和权重进行统计和记录,并且定义一个可以筛选出最小权重的函数。初始化树节点之后开始建立哈夫曼树。先在所有可能出现的字符中筛选出当前权重最小的两个字符,将这两个字符分别作为新节点的左子和右子建立一个小的二叉树,并将两个字符的权重之和赋值给新节点,将新二叉树放入筛选字符中,再将筛选过的两个字符从筛选列表中淘汰掉。依次对列表中剩下的字符进行权重最小的筛选,直到根节点(如果编码表共有N个字符,则2*N-1就为最终根节点)为止,也就是当筛选列表为空的时候,哈夫曼树即建立完成。对于哈夫曼编码树来说,由于哈夫曼

4、编码是前缀码,所以所有要编码的字符最终都将是这颗树的叶子节点,而其它节点并没有真正的字符意义。即当哈夫曼编码树建立之后,对树的所有叶子节点进行打印可知道是否有字符遗漏或多余。建立哈夫曼编码表。建立编码表时要根据每个出现的字符的权重对建立的哈夫曼树的每个叶子节点进行编码。编码时要从叶子节点出发向根节点进行逆向编码。判断如果当前节点为左子则对其编码0,如果当前节点为右子则对其编码1。以此类推进行编码直到根节点为止。此时的编码是逆向的,所以需要将码值逆向存储。依次对每一个叶子节点进行编码操作,即可得到当前哈夫曼树的编码表。对于码值的逆向存储可以使用栈结构,先将一个码的每一步编码存入栈,再在一个码结束

5、后出栈至空。当然也可以定义一个字符型数组,将值从后向前存入数组,再将数组有值部分粘贴到新的数组中进行存储。本次采用了后者,因为个人认为为此一步操作建立栈结构不划算,而且前一个设计也已经熟练掌握了栈的方法,此处进行新的尝试会更好。对文件进行编码。首先需要建立一个原始文件,在文件中输入需要编码的内容。之后将文件打开,将其中的内容存储到字符串中以便程序编码调用。开始对需要编码的字符进行编码,将字符逐一读取与刚刚建立的编码表中的每个叶子节点代表的字符进行比较,找出相同的对象,并将当前节点的编码打印到屏幕,并将编码存入到新建的密码文件当中。对文件进行解码。先打开密码文件,将之前编码后得到的密文内容存储到

6、字符串中以便解码调用。开始对密文的字符串进行解码,树索引从根节点开始走,当密文中的当前字符是0的时候,则索引走向左子节点;当是1的时候,则走向右子节点。以此类推,一直走到叶子节点为止,则当前叶子节点所代表的字符即为前一段密文的解码结果,。再对下一个字符依次从根节点开始解码,如此循环对每一段密文进行解码直到解码结束。将解码打印到屏幕,并将解码结果存入到新的解码文件当中。在解码之前,还应该先确认之前是否建立了哈夫曼树并且是否构建了编码表。不过由于本次将a到z都进行了编码,所以此步省略了,因为编码表是唯一的。需要的时候可以在Encoder 函数中先进行判定。将编码和解码写在了一起,可以在运行时进行选

7、择调用。三、实验内容1.使用matlab 实现香农码和Huffman 编码,并自己设计测试案例。2.使用CC+实现香农码和Huffman 编码,并自己设计测试案例。3.可以用任何开发工具和开发语言,尝试实现Huffman 编码应用在数据文件的压缩和解压缩中,并自己设计测试案例。四、实验要求1. 提前预习实验,认真阅读实验原理以及相应的参考书。2. 认真高效的完成实验,实验中服从实验室管理人员以及实验指导老师的管理。3. 认真撰写实验报告,内容可以自己编排,可以考虑包括以下一些方面:原理概述、程序设计与算法描述、源程序及注释(程序太长可以只选取重要部分)、运行输出结果实例、调试和运行程序过程中产

8、生的问题及采取的措施、对实验的讨论分析、总结。五、调试结果香农编码:哈夫曼编码:C语言之香农编码:C语言之哈夫曼编码:六、代码Matlab实现香农编码:clear;A=input(please input a number:) %提示输入界面A=fliplr(sort(A);%降序排列m,n=size(A);for i=1:n B(i,1)=A(i);%生成B的第1列end%生成B第2列的元素a=sum(B(:,1)/2;for k=1:n-1 if abs(sum(B(1:k,1)-a)=abs(sum(B(1:k+1,1)-a) break; endendfor i=1:n%生成B第2列的

9、元素 if i=k B(i,2)=0; else B(i,2)=1; endend%生成第一次编码的结果END=B(:,2);END=sym(END);%生成第3列及以后几列的各元素j=3;while (j=0) p=1; while(p=n) x=B(p,j-1); for q=p:n if x=-1 break; else if B(q,j-1)=x y=1; continue; else y=0; break; end end end if y=1 q=q+1; end if q=p|q-p=1 B(p,j)=-1; else if q-p=2 B(p,j)=0; END(p)=char

10、(END(p),0; B(q-1,j)=1; END(q-1)=char(END(q-1),1; else a=sum(B(p:q-1,1)/2; for k=p:q-2 if abs(sum(B(p:k,1)-a)=abs(sum(B(p:k+1,1)-a); break; end end for i=p:q-1 if i=k B(i,j)=0; END(i)=char(END(i),0; else B(i,j)=1; END(i)=char(END(i),1; end end end end p=q; end C=B(:,j); D=find(C=-1); e,f=size(D); if

11、e=n j=0; else j=j+1; endendBAENDfor i=1:n u,v=size(char(END(i); L(i)=v;endavlen=sum(L.*A)哈夫曼编码:p=input(please input a number:) %提示输入界面 n=length(p); for i=1:n if p(i)0 fprintf(n The sum of the probabilities in huffman can more than 1!n); p=input(please input a number:) %如果输入的概率数组总和大于1,则重新输入概率数组 endq=

12、p; a=zeros(n-1,n); %生成一个n-1 行n 列的数组 for i=1:n-1 q,l=sort(q); %对概率数组q 进行从小至大的排序,并且用l 数组返回一个数组,该数组表示概率数组q 排序前的顺序编号 a(i,:)=l(1:n-i+1),zeros(1,i-1); %由数组l 构建一个矩阵,该矩阵表明概率合并时的顺序,用于后面的编码 q=q(1)+q(2),q(3:n),1; %将排序后的概率数组q 的前两项,即概率最小的两个数加和,得到新的一组概率序列 endfor i=1:n-1 c(i,1:n*n)=blanks(n*n); %生成一个n-1 行n 列,并且每个元

13、素的的长度为n 的空白数组,c 矩阵用于进行huffman 编码,并且在编码中与a 矩阵有一定的对应关系 endc(n-1,n)=0; %由于a 矩阵的第n-1 行的前两个元素为进行huffman 编码加和运算时所得的最 c(n-1,2*n)=1; %后两个概率,因此其值为0 或1,在编码时设第n-1 行的第一个空白字符为0,第二个空白字符1。 for i=2:n-1 c(n-i,1:n-1)=c(n-i+1,n*(find(a(n-i+1,:)=1)-(n-2):n*(find(a(n-i+1,:)=1); %矩阵c 的第n-i 的第一个元素的n-1 的字符赋值为对应于a 矩阵中第n-i+1

14、 行中值为1 的位置在c 矩阵中的编码值 c(n-i,n)=0; %根据之前的规则,在分支的第一个元素最后补0 c(n-i,n+1:2*n-1)=c(n-i,1:n-1); %矩阵c 的第n-i 的第二个元素的n-1 的字符与第n-i 行的第一个元素的前n-1 个符号相同,因为其根节点相同 c(n-i,2*n)=1; %根据之前的规则,在分支的第一个元素最后补1 for j=1:i-1 c(n-i,(j+1)*n+1:(j+2)*n)=c(n-i+1,n*(find(a(n-i+1,:)=j+1)-1)+1:n*find(a(n-i+1,:)=j+1); %矩阵c 中第n-i 行第j+1 列的

15、值等于对应于a 矩阵中第n-i+1 行中值为j+1 的前面一个元素的位置在c 矩阵中的编码值 endend %完成huffman 码字的分配 for i=1:n h(i,1:n)=c(1,n*(find(a(1,:)=i)-1)+1:find(a(1,:)=i)*n); %用h 表示最后的huffman 编码,矩阵h的第i 行的元素对应于矩阵c 的第一行的第i 个元素 ll(i)=length(find(abs(h(i,:)=32); %计算每一个huffman 编码的长度 enddisp(二元Huffman编码平均码长) l=sum(p.*ll); %计算平均码长 disp(l)%fprin

16、tf(n huffman code:n); h disp(信源熵) hh=-sum(p.*log2(p) %计算信源熵 %fprintf(n the huffman effciency:n); disp(编码效率) t=hh/l %计算编码效率C语言实现香农编码:#include#include#include#includeclass Tpublic: T() T(); void Create(); void Coutpxj(); void Coutk(); void Coutz(); void Print();protected: int n; double *p; double *pxj

17、; int *k; double *mz;void T:Create() coutn; p=new doublen; cout请输入这几个n概率:n; int i; for(i=0;ipi; pxj=new doublen; k=new intn; mz=new doublen; double sum=0.0; for(i=0;in;i+) sum+=pi; if(sum!=1.0) throw 1; else for(i=0;in;i+) int k=i; for(int j=i+1;jn;j+) if(pkpj) k=j; double m=pi; pi=pk; pk=m; T:T() d

18、elete p; delete pxj; delete k; delete mz;void T:Coutpxj() pxj0=0; for(int i=1;in;i+) pxji=0; for(int j=0;ji;j+) pxji+=pj; void T:Coutk() for(int i=0;i0) ki=(int)d+1; else ki=(int)d; void T:Print() coutXisetw(8)P(xi) setw(8)Pa(xj) setw(8)Ki setw(8)码字 endl; int i; for(i=0;in;i+) coutXi+1 setw(8)setpre

19、cision(2)pi setw(8)setprecision(2)pxji setw(8)ki ; mzi=pxji; for(int j=0;j=0) cout1; mzi=2*mzi-1; else cout0; mzi=2*mzi; coutendl; double K=0.0,H=0.0,Y; for(i=0;in;i+) K+=(double)pi*ki; H+=(-1)*pi*(log10(pi)/log10(2.0); Y=H/K; cout平均码长:Kendl; cout信源熵:Hendl; cout编码效率:Yendl;void main() T t;int e; try

20、t.Create(); t.Coutpxj(); t.Coutk(); t.Print(); catch(int e) if(e=1) cout输入错误,请重新运行;哈夫曼编码:#include #include #include #define MAXLEN 100typedef struct int weight; int lchild; int rchild; int parent; char key;htnode;typedef htnode hfmtMAXLEN;int n;void inithfmt(hfmt t)/对结构体进行初始化 int i; printf(n); print

21、f(-n); printf(*输入区*n); printf(n请输入n=); scanf(%d,&n); getchar(); for(i=0;i2*n-1;i+)/对结构体进行初始化 ti.weight=0; ti.lchild=-1; ti.rchild=-1; ti.parent=-1; printf(n); void inputweight(hfmt t)/输入函数 int w;/w表示权值 int i; char k;/k表示获取的字符 for(i=0;in;i+) printf(请输入第%d个字符:,i+1); scanf(%c,&k); getchar(); ti.key=k;

22、printf(请输入第%d个字符的权值:,i+1); scanf(%d,&w); getchar(); ti.weight=w; printf(n); void selectmin(hfmt t,int i,int *p1,int *p2)/选中两个权值最小的函数 long min1=999999; long min2=999999; int j; for(j=0;jtj.weight) min1=tj.weight; *p1=j; for(j=0;jtj.weight & j!=(*p1)/注意 j!=(*p1) min2=tj.weight; *p2=j; void creathfmt(h

23、fmt t)/创建哈夫曼树的函数 int i,p1,p2; inithfmt(t); inputweight(t); for(i=n;i2*n-1;i+) selectmin(t,i-1,&p1,&p2); tp1.parent=i; tp2.parent=i; ti.lchild=p1; ti.rchild=p2; ti.weight=tp1.weight+tp2.weight; void printhfmt(hfmt t)/打印哈夫曼树 int i; printf(-n); printf(*哈夫曼编数结构:*n); printf(tt权重t父母t左孩子t右孩子t字符t); for(i=0;

24、i2*n-1;i+) printf(n); printf(tt%dt%dt%dt%dt%c,ti.weight,ti.parent,ti.lchild,ti.rchild,ti.key); printf(n-n); printf(nn); void hfmtpath(hfmt t,int i,int j)/编码的重要哈夫曼树路径递归算法 int a,b; a=i; b=j=ti.parent; if(tj.parent!=-1) i=j; hfmtpath(t,i,j); if(tb.lchild=a) printf(0); else printf(1); void phfmnode(hfmt t)/对字符进行初始编码 int i,j,a; printf(n-n); printf(*哈夫曼编码*); for(i=0;in;i+) j=0; printf(n); printf(tt%ct,ti.key,ti.weight); hfmtpath(t,i,j); printf(n-n); void encoding(hfmt t)/对用户输入的电文进行编码 char r1000;/用来存储输入的字符串

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

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