合肥工业大学 信息论与编码 实验报告 完整代码版综述文档格式.docx

上传人:b****1 文档编号:12990422 上传时间:2022-10-01 格式:DOCX 页数:91 大小:438.68KB
下载 相关 举报
合肥工业大学 信息论与编码 实验报告 完整代码版综述文档格式.docx_第1页
第1页 / 共91页
合肥工业大学 信息论与编码 实验报告 完整代码版综述文档格式.docx_第2页
第2页 / 共91页
合肥工业大学 信息论与编码 实验报告 完整代码版综述文档格式.docx_第3页
第3页 / 共91页
合肥工业大学 信息论与编码 实验报告 完整代码版综述文档格式.docx_第4页
第4页 / 共91页
合肥工业大学 信息论与编码 实验报告 完整代码版综述文档格式.docx_第5页
第5页 / 共91页
点击查看更多>>
下载资源
资源描述

合肥工业大学 信息论与编码 实验报告 完整代码版综述文档格式.docx

《合肥工业大学 信息论与编码 实验报告 完整代码版综述文档格式.docx》由会员分享,可在线阅读,更多相关《合肥工业大学 信息论与编码 实验报告 完整代码版综述文档格式.docx(91页珍藏版)》请在冰豆网上搜索。

合肥工业大学 信息论与编码 实验报告 完整代码版综述文档格式.docx

并实现相应的译码操作。

二、提升要求

对一幅BMP格式的灰度图像进行二元霍夫曼编码。

三、问题描述

1、三元霍夫曼编码首先需要考虑的是如何表示三元

2、三元霍夫曼编码需要对不满足2n+3的情况做处理

3、使用什么数据结构建立霍夫曼树

四、算法思想

1、使用两个二进制位表示一个三元变量,即00表示a、01表示b、11表示c。

2、出现不满足2n+3情况即需要加入一个出现次数为0次的字符,遍历已经出现的字符,找到一种八位二进制组合作为新字符。

3、建立霍夫曼树的算法,使用数组的结构作为整棵树的空间,其中每个数组元素是一个类的实例。

在这各类里封装了他所代表的字符(如果不是叶子节点则为null)、出现的次数(非叶子结点则为子节点的此项加和)。

承载整棵树的数组也是封装在一个类里的,这个类同时封装了对这棵树的操作,如添加节点、树节点排序等,这样就可以使从添加叶子节点后建立整棵霍夫曼树。

5、模块划分

charhuancun[max];

//从文件中读入的字符

charyasuohuancun[max];

//压缩后可以写进文件中的字符串

longintyasuohuancunnumber=0;

//准备写入文件中的个数

longinthuancunnumber=0;

//从文件中读出字符个数

classtree

{voidset(inta,intb,intc,intd,inte)//次数为a,左孩子为b,中孩子为c,右孩子为d,自己的编号e

intmynumber;

//次数

intleftsonnumber;

//数组编号

intmiddlesonnumber;

intrightsonnumber;

//数组编号控制时没有儿子节点则儿子都是负数

intmyzifunumber;

//作为叶子节点在数组中的编号

};

classtable//压缩对照表

{

public:

table()

voidcutrealfile()//将缓存中一样的字符区别开

voiduncheck(charhuancun)//检查是否出现过字符

boolcheck(charhuancun)//检查源文件字符是否出现过

intcheckhuancun(inti)//读缓存数组的字符,返回yasuozifu数组中的地址

voidcount(treefun[],intbegin,intend)//begin~end区间内排序

charh3setonechar(charn1,charn2,charn3,charn4)//三元霍夫曼给进一个char

位操作使用内联汇编语言d是不会被译码的为了补齐余码

voidlinshih3manage(charptr)//进来字符存起来每四个存一个

voidwritesign(treefun[],intpermitnumber,chark,intfuthernumber)//先给sign的值

递归构建霍夫曼树

voidhafuman3()//三元霍夫曼编码函数

voidcodemanage()//对整个缓存进行编码

boolcheckh3code(stringptr)//对解压缩后的码串译码

voidjiemah3code(charptr)//对一个char型8位进行解码为4个char型

voiddiscodemanage()//解压缩程序使用huancun[]放密文,解压后原文放在yasuohuancun[]中

charlinshih3[4];

//临时三元霍夫曼

intlinshih3number;

//记录临时三元霍夫曼个数

intnumber;

//未压缩字符的数量

inteveryzifunumber[max];

//每个字符出现的次数

stringsign[max];

//压缩后的字符(先用数字表示)

stringpaixusign[max];

//编码后与paxu字符数组对应的编码

charpaixuzifu[max];

//和字符数组一样,顺序对应paixusign

charzifu[max];

//未压缩的字符(互不相同)

voidreadfile(constchar*realfile)//文件读入缓存

voidwritefile(constchar*yasuofile)//缓存写入文件

intmain()//主函数

readfile(realfile);

tablemytable;

mytable.cutrealfile();

mytable.hafuman3();

mytable.codemanage();

writefile(yasuofile);

readfile(yasuofile);

mytable.discodemanage();

writefile(jieyasuofile);

return0;

}

6、测试数据

2.txt文件

n999.bmp文件

1、2.txt文件

hellomarkchalse,

thisisasecret

number6424155

pleaseputthisinancode

小刀司令

压缩后:

將埼绩髱釜#?

庩宏壕ǔ券?

€:

焕?

0鼜>

?

姾嫧偪瘞旰?

3?

飶卡8*

解压缩后(最后多了一字节空格):

小刀司令

压缩情况:

源文件:

压缩文件:

解压缩文件:

编码分析:

无损压缩压缩率:

74.16%

2、n999.bmp

解压缩

无失真压缩

7、源程序(见附录)

实验2算术编码

一、基本要求

对任意输入的字符串序列进行自适应编码,并设计相应的译码

二、提升要求

对一幅bmp格式的灰度图像进行自适应算术编码,并设计相应的译码

三、问题描述

1、算术编码的过程实际就是对两个小数确定的取区间,划分区间,再取区间不断重复的过程,将采用什么数据结构。

2、自适应编码如何确定小数的误差以保证无误差即零失真

3、Longdouble只有二十几位如何压缩更多的内容

1、将上边界,下边界分别记录,并封装在一个类中。

类中还封装了对区间选择、改变上界下界值的函数等。

2、区计算后的各字符概率的小数后八位保证无误差

3、为保证压缩足够多的量,不采用longdouble记录上下界的值,而是采用int型数组来记录上下界的值,每个longint取七位十进制数。

这样初始max值为10000,所以整个算法可以进行小数点后70000位的小数加减乘除取对数等运算,保证了可压缩量

五、模块划分

因为要进行长数位计算所以用一个longint[]的数组将每个单元表示7位十进制数按max=10000的初始可以达小数点后70000位

在存储大数时数组按距离小数点越近越靠左的顺序码放

用一个类封装数据和操作方便对数据的掉用,省得一会形参一会实参下边界为准

注意length[]中是按照小数的格式如果某一元组其不满7位则前面为0将length[]连起来表示数时一定要注意

步骤:

1、将原文件读入缓存

2、统计原文件字符的种类有多少频率分别是多少(自适应)

提示:

计算频率doublec=double(a)/double(b);

3、接下来在arithmetic_coding中根据缓存中每个字符获得最后的概率

getposible(char)得到给定字符的概率区间

getlength()计算区间长度

intgetint(double)将概率小数转化成整数

classposible_8:

:

set(int)lowposiblehighposible在这里先通过getint()转化为8位整数再变成4个2位的整数方便计算

接下来用posible_8的每一个数组元素(两位)从length[]最后开始乘并向前进位

mathmatic:

intgetreallength()//得到length[]数字的准确位数

intgetlong()//得到every2bit[]的小数位长

intgetbeginlength()//得到length[]数字的从开始到最后一个数字的准确位数

voiddealhigh()//high=low+lowposible*length=low+length(已处理)

voidcuthigh()//high后面不需要的为零的元组要约去

voiddeallow()//low=low+lowposible*length=low+length(已处理)

voidcutlow()//low后面不需要的为零的元组要约去

4、mathmatic:

voidcode()将最后的low[]进行二进制编码存入yasuohuancun[]中

#include<

math.h>

之后就可以直接使用log了以2为底的对数可以用换底公式表示log(n)/log

(2)

不能用log()求一个数组表示的大数的原因是log(a+b)根本无法拆解啊不要说把a+b分解成c*d*.......

但我们可以使用简单粗暴的0.5*0.5*0.5.......迭代进行直到找到那个整数部分

intgetlog()//返回log(length)

intchecksize(longintgoal[max],intgoalnumber,longintlow[max],intlownumber)//比较两个正规小数大小goal小返回1大0相等2

voiddealmycode()//将mycode中的十进制表示的二进制转化为二进制存入yasuohuancun[]中

5、mathmatic:

voiddiscode()//解压缩压缩文件已读入huancun[]第一个是以前的huancunnumber

mathmatic:

voiddeal8bit(charkp,intoverbit)//计算nowlow

voidaddnowlow()//low+nowlow

discode()现在low已经有了,接下来需要比较yasuohuancunnumber次就可以还原以前的huancun[]了

不过需要重用nowlow[]作为目标小数low[]每次需要做运算

intgetzifu()函数中代码重用:

重用arithmetic_cod

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

当前位置:首页 > 工程科技 > 纺织轻工业

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

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