合肥工业大学信息论与编码试验报告完整代码版讲解_第1页
合肥工业大学信息论与编码试验报告完整代码版讲解_第2页
合肥工业大学信息论与编码试验报告完整代码版讲解_第3页
合肥工业大学信息论与编码试验报告完整代码版讲解_第4页
合肥工业大学信息论与编码试验报告完整代码版讲解_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、计算机与信息学院 信息论与编码 实验报告 专业班级 信息安全 13-1 班 学生姓名及学号 马骏 2013211869 课程教学班号 任课教师 苏兆品 实验指导教师 苏兆品 实验地点 逸夫楼 2014 2015 学年第 一 学期 实验 1 霍夫曼编码 一、基本要求 通对任意输入的字符串序列进行 3元霍夫曼编码,给出编码结果、 编码效率; 并实现相应的译码操作。 二、提升要求 对一幅 BMP 格式的灰度图像进行二元霍夫曼编码。 三、问题描述 1、三元霍夫曼编码首先需要考虑的是如何表示三元 2、三元霍夫曼编码需要对不满足 2n+3 的情况做处理 3、使用什么数据结构建立霍夫曼树 四、算法思想 1、

2、使用两个二进制位表示一个三元变量,即 00 表示 a、01 表示 b、11 表 示 c 。 2、出现不满足 2n+3情况即需要加入一个出现次数为 0 次的字符,遍历已 经出现的字符,找到一种八位二进制组合作为新字符。 3、建立霍夫曼树的算法, 使用数组的结构作为整棵树的空间, 其中每个数 组元素是一个类的实例。 在这各类里封装了他所代表的字符(如果不是叶子节点则为null )、出现 的次数(非叶子结点则为子节点的此项加和) 。 承载整棵树的数组也是封装在一个类里的, 这个类同时封装了对这棵树的 操作,如添加节点、 树节点排序等, 这样就可以使从添加叶子节点后建立整棵霍 夫曼树。 五、模块划分

3、char huancunmax;/从文件中读入的字符 char yasuohuancunmax;/压/ 缩后可以写进文件中的字符串 long int yasuohuancunnumber=0;/准/ 备写入文件中的个数 long int huancunnumber=0;/从文件中读出字符个数 class tree void set(int a,int b,int c,int d,int e)/ 次数为 a,左孩子为 b,中孩子为 c,右孩子为 d,自己的编号 e int mynumber;/次数 int leftsonnumber;/数组编号 int middlesonnumber; int

4、rightsonnumber;/数组编号 控制时没有儿子节点则儿子都是负数 int myzifunumber;/ 作为叶子节点在数组中的编号 ; class table/压缩对照表 public:table() void cutrealfile()/ 将缓存中一样的字符区别开 void uncheck(char huancun)/检/ 查是否出现过字符 bool check(char huancun)/检/ 查源文件字符是否出现过 int checkhuancun(int i)/读缓存数组的字符,返回 yasuozifu 数组中的地址 void count(tree fun,int begin

5、,int end)/beginend 区间内排序 char h3setonechar(char n1,char n2,char n3,char n4三)/元霍夫曼给进一个 char 位操作使用内联汇编语言 d 是不会被译码的 为了补齐余码 void linshih3manage(char ptr)/进来字符存起来 每四个存一个 void writesign(tree fun,int permitnumber,char k,int futhernumber)/ 先给 sign 的值 递归构建霍夫曼树 void hafuman3()/三元霍夫曼编码函数 void codemanage()/对整个缓

6、存进行编码 bool checkh3code(string ptr)/对解压缩后的码串译码 void jiemah3code(char ptr)/对一个 char型 8 位进行解码为 4 个 char型 void discodemanage()/解压缩程序 使用 huancun放密文,解压后原文放在 yasuohuancun中 char linshih34;/ 临时三元霍夫曼 int linshih3number;/ 记录临时三元霍夫曼个数 int number;/未压缩字符的数量 int everyzifunumbermax;/ 每个字符出现的次数 string signmax;/ 压缩后的

7、字符 (先用数字表示 ) string paixusignmax;/编码后与 paxu 字符数组对应的编码 char paixuzifumax;/ 和字符数组一样,顺序对应 paixusign char zifumax;/未压缩的字符 (互不相同 ) ; void readfile(const char* realfile) /文件读入缓存 void writefile(const char*yasuofile)/ 缓存写入文件 int main()/ 主函数 readfile(realfile); table mytable; mytable.cutrealfile(); mytable.h

8、afuman3(); mytable.codemanage(); writefile(yasuofile); readfile(yasuofile); mytable.discodemanage(); writefile(jieyasuofile); return 0; 六、测试数据 2.txt 文件 n999.bmp文件 1、2.txt 文件 hello markchalse, this is a secret number 6424155 please put this in an code 小刀司令 压缩后: 將埼 绩髱釜 #?庩宏壕券? ? :,焕?0 鼜?姾嫧偪瘞旰 ?3? ?飶卡

9、8* 解压缩后(最后多了一字节空格) : hello markchalse, this is a secret number 6424155 please put this in an code 小刀司令 压缩情况: 源文件: 压缩文件: 解压缩文件: 编码分析: 无损压缩 压缩率: 74.16% 2、 n999.bmp 压缩后: 解压缩 无失真压缩 七、源程序 (见附录) 实验 2 算术编码 一、基本要求 对任意输入的字符串序列进行自适应编码,并设计相应的译码 二、提升要求 对一幅 bmp 格式的灰度图像进行自适应算术编码,并设计相应的译码 三、问题描述 1、算术编码的过程实际就是对两个小数

10、确定的取区间,划分区间,再取区 间不断重复的过程,将采用什么数据结构。 2、自适应编码如何确定小数的误差以保证无误差即零失真 3、Long double 只有二十几位 如何压缩更多的内容 四、算法思想 1、将上边界,下边界分别记录,并封装在一个类中。类中还封装了对区间 选择、改变上界下界值的函数等。 2、区计算后的各字符概率的小数后八位保证无误差 3、为保证压缩足够多的量,不采用 long double 记录上下界的值,而是采用 int 型数组来记录上下界的值,每个 long int 取七位十进制数。这样初始 max 值 为 10000,所以整个算法可以进行小数点后 70000 位的小数加减乘

11、除取对数等运 算,保证了可压缩量 五、模块划分 因为要进行长数位计算 所以用一个 long int 的数组将每个单元表示 7 位十进制 数 按 max=10000 的初始 可以达小数点后 70000 位 在存储大数时数组按距离小数点越近越靠左的顺序码放 用一个类封装数据和操作方便对数据的掉用, 省得一会形参一会实参下边界为准 注意 length 中是按照小数的格式 如果某一元组其不满 7 位则前面为 0 将 length 连起来表示数时 一定要注意 步骤: 1、将原文件读入缓存 2、统计原文件字符的种类有多少 频率分别是多少 (自适应 ) 提示:计算频率 double c=double(a)/

12、double(b); 3、接下来 在 arithmetic_coding 中 根据缓存中每个字符 获得最后的概率 getposible(char)得到给定字符的概率区间 getlength()计算区间长度 int getint(double)将概率小数转化成整数 class posible_8:set(int) lowposible highposible 在这里先通过 getint() 转化为 8 位整数再变成 4 个 2 位的整数方便计算 接下来用 posible_8 的每一个数组元素 (两位)从 length 最后开始乘并向 前进位 mathmatic:int getreallength

13、()/得到 length 数字的准确位数 class posible_8:int getlong()/得到 every2bit 的小数位长 mathmatic:int getbeginlength()/得到 length 数字的从开始到最后一个数 字的准确位数 mathmatic:void dealhigh()/high=low+lowposible*length=low+length( 已 处理) mathmatic:void cuthigh()/high 后面不需要的为零的元组要约去 mathmatic:void deallow()/low=low+lowposible*length=lo

14、w+length( 已处 理) mathmatic:void cutlow()/low 后面不需要的为零的元组要约去 4、mathmatic:void code()将最后的 low 进行二进制编码存入 yasuohuancun 中 #include之后就可以直接使用 log 了 以 2 为底的对数可以用换 底公式表示 log(n)/log(2) 不能用 log() 求一个数组表示的大数的原因是 log(a+b)根本无法拆解啊 不要说把 a+b 分解成 c*d* 但我们可以使用简单粗暴的 0.5*0.5*0.5 迭代进行直到找到那个整 数部分 mathmatic:int getlog()/返回

15、log(length) mathmatic:int checksize(long int goalmax,int goalnumber,long int lowmax,int lownumber)/ 比较两个正规小数大小 goal 小返回 1 大 0 相等 2 mathmatic:void dealmycode()/将 mycode 中的十进制表示的二进制转化 为二进制存入 yasuohuancun中 5、mathmatic:void discode()/解压缩 压缩文件已读入 huancun 第一个是 以前的 huancunnumber mathmatic:void deal8bit(cha

16、r kp,int overbit)/ 计算 nowlow mathmatic:void addnowlow()/low+nowlow discode()现在 low 已经有了,接下来需要比较 yasuohuancunnumber次就 可以还原以前的 huancun了 不过需要重用 nowlow 作为目标小数 low 每次需要做运算 int getzifu() 函数中代码重用:重用 arithmetic_coding()代码 直接用 checksize() BUG: discode()不知道为什么要减 1 最后一个字符 11111111 这个 bug 还没有修 复 这个 bug 非常严重 导致如

17、原文件内容为 abc 无法 六、测试数据 2.txt 文件 n77.bmp文件 1、 2.txt 文件 hello markchalse, this is a secret number 6424155 please put this in an code 小刀司令 压缩后: 稬?睖?反.媹录? 缶m郜緕 k?.?=X 杛?楞璩 t m?桶 程序过程: 解压缩后: hello markchalse, this is a secret number 6424155 please put this in an code 小刀司令 压缩情况: 源文件: 压缩文件: 解压缩文件: 编码分析: 无损压缩

18、 压缩率: 65.17% 2、 n77.bmp 压缩文件: 傝 ?靯左 =W 噀Z 鐢?霑楞壗 YO? 濖? 痦? 畝? 湍叚 ?Jz ? V 摮|_ p 濔?褺 S ?老 z7?t J?料 c鶻 H 娀止 程序过程: D:c-documentsfgs 论 信亘论 算术编码 Debugmath(疙淨茨).exh 10:78,263411,2332226,4315429.8369315,1372957,1784012,590393,873215,8851074,478 0468.5309889,3979622,3015751,G730G12,7453833,G054052,1949839,118

19、451G27089Z8G642 24,3383076,4691437,6412119,2955804,7098507,4674067,4100080,314564,5834474,877349 0,1532104,6943410,465639,5548495,5633905,7290173,7767684,7818583,417914,8559677,1 3628584,4728913,6051355,9190989,4674712.3637481,3489716,2394153,6187558,1964879 J 4215944,5707779,5050468,4783024,5114879

20、,3272791,5129526,6810057,9177438,8135131J 5829529,2170001,7216663,1847576,1691116,5536133,9326002,4319007,1624106,3302806 J 74602B8.3872845.1368963,1399818,8039721,9643871,2164454.6744416,8299454,6174661. 2336041,5456759,8843833,6555714,547788,8908389,3991805,367756,440062,5138285,216 5779,4808280,2

21、707692,6333753,1223089,8276400,8310302,2464233,9854158,2458541,673 6403,9750730.1385957,4711280.50824707121282,3864014.493223,5781212.815540.23565 71,9373679,5394388,4223946,9423895,1649693,2708429,6862645,286698,9847743,367350 8,1784236,81457,9351476,2061610,1838009,2389304,9668644,4317701,9758878,

22、7158104, 2966770.7103387.4333811,200193.3566604,4803088286158.1305006,3265147.2180460.9 706406,8778781,6737662,6740196,6988487,1559336,4361615,1560314,9642023,1666424,8 973988.274324.894888S.6415338,85090831920501.9141779,86531601715941.8987171,76 2976R, 7971 78.574?;70,21 B4201 .24胸化212耽4?“191 77.眄

23、9竹2加4 9.4影?2.920彳 801,4541686,1503409,3521264,8194792,3929349,327678,1899836,7914672,6820511,19589 22/102053?,76U2492,2239931.475112U,322164,5115kJ25,542M327,1302372,25926/U,755372 1.75271 , 9296383, (;72R91R. 319381R. 841113.87726,79219!;1.5873530,5963RA8,8976 A?;9 J 4290442,2104309,5999770,8683962

24、,5733509,6810984,3828287,5159987,8245237,813146,? y7803.ZU34503,3614746.3635747,564126.75653.2 513581363586.1252519.7746209.8153336.1945564.2801192.4679268.4429919.6925260.21 79701,8763411,937097,6905697,7444576,1498498,4133340,7435496,1780616,5955115,429 7638,846874. !/6036!?8,4?48066,7886159.32306

25、40,563)66, 784845,57kJ36,2413267,33722 935R4S235.8459226.993A13R A99G22S.491 (H 61 1 97541 B 1453239 33,3932716,1067616,8487562,4349218,2685466,9026412,3238781,9171608,7587293,39631 22,358413.4877339,6696761.5829261,9270266,5510852546722,9348945,2437559,3475591 .4867866,7752586,2422593,1289371.99945

26、44,2345383.2959801,3747851.2402430.2247699 ,619670,7888368,718582,7530779,4850422,9537128,8573066,1743136,6285627,6624270,5 2996872749817,5464008,21503761053411,4529809,1260000,5108824,6106409,4926439.9 231174,6856504,8052551,111009,3385959,8575131,4249615,2670469,6207982,5089025,90 17741,7058600,48

27、40725,8288365,7372447,6075922,1838558,9481606,645652,6953210,317 8025,2658823,8389307,2504629,4X50029,7160120,7940096.6823031,9206667,7412470,923| 2018,956760,9455464,2467428,4155313,5871684,5027254,5809391,9131624,1737907,3188 581,6542164,354872,1358228,7193532,9618552,1879665,8792605,5455798,50009

28、36,40994 90,8763756,2061448,7532643,492122,9308717,4617071,8873122,5044624,282019 JL,856224 ,8055835,1822514,1550594,9727675,5395896,7213355,4396942,2293682,1310092,4528099 ,7728999,6111612,9490973,495522,2637336,9946761,4152738,62987,3657054,9498025,11 02530,6201955,7851456,2829297,526385,9632114,2

29、399781,5490535,9803491,2183433.934 E387,903846,8934928,4331520, Ibegin coding 解压缩后: 压缩情况: 源文件: 压缩文件: 解压缩文件: 编码分析: 无损压缩 压缩率: 32.96% 七、源程序 (见附录) 八、总结 通过此次实验,我在学习编码原理的进一步学习了各种无失真信源编码的编 程方法,使我对信息论与编码有了更深的了解。程序中还存在很多的不足,希 望在以后的学习中可以做到更加完善。 附录 Hafuman.cpp /* 基本要求:对任意输入字符串进行三元哈弗曼编码 */ #include #include #in

30、clude #include using namespace std; const char* realfile=n77.bmp; const char* yasuofile=n3.txt; const char* jieyasuofile=n4.bmp; const int max=10000; char huancunmax;/从文件中读入的字符 char yasuohuancunmax;/压/ 缩后可以写进文件中的字符串 long int yasuohuancunnumber=0;/准/ 备写入文件中的个数 long int huancunnumber=0;/从文件中读出字符个数 cla

31、ss tree public: tree(); void set(int a,int b,int c,int d,int e)/次数为 a,左孩子为 b,中孩子为 c,右孩子 为 d ,自己的编号 e mynumber=a; leftsonnumber=b; middlesonnumber=c; rightsonnumber=d; myzifunumber=e; ; int mynumber;/次数 int leftsonnumber;/数组编号 int middlesonnumber; int rightsonnumber;/数组编号 控制时没有儿子节点则儿子都是负数 int myzifun

32、umber;/ 作为叶子节点在数组中的编号 ; class table/压缩对照表 public:table() number=0; linshih3number=0; ; void cutrealfile()/ 将缓存中一样的字符区别开 int x; for(x=0;xnumber/2)/ 三元霍夫曼满足 2n+3 不就是奇数 还没考虑 1 以后注意维护 coutright number!endl; else coutwrong number!endl; char tmd;/寻找不可能出现的 8 位二进制数 tmd _asm mov tmd,01001101b; if(check(tmd)

33、zifunumber=huancunx; everyzifunumbernumber=0; number+; else uncheck(tmd); _asm mov tmd,01101001b; if(check(tmd) zifunumber=huancunx; everyzifunumbernumber=0; number+; else uncheck(tmd); coutzifuendl; for(x=0;xnumber;x+) coutzifux 次数: everyzifunumberxendl; coutnumber=numberendl; ; void uncheck(char h

34、uancun)/检/ 查是否出现过字符 int x; for(x=0;xnumber;x+) if(zifux=huancun) everyzifunumberx-; ; bool check(char huancun)/检/ 查源文件字符是否出现过 int x; for(x=0;xnumber;x+) if(zifux=huancun) everyzifunumberx+; return false; return true; ; int checkhuancun(int i)/读缓存数组的字符,返回 yasuozifu 数组中的地址 char a=huancuni; int x=0; fo

35、r(x=0;xnumber;x+) if(paixuzifux=a) return x; return -1; ; void count(tree fun,int begin,int end)/beginend 区间内排序 int x,y; tree a; for(x=begin;xend-1;x+) for(y=x+1;yfuny.mynumber) a=funx; funx=funy; funy=a; ; char h3setonechar(char n1,char n2,char n3,char n4)/三元霍夫曼给进一个 char 位操作使用内联汇编语言 /d 是不会被 译码的 为了补

36、齐余码 char onechar; if(n1=a) _asm mov onechar,00h; if(n1=b) _asm mov onechar,11000000b; if(n1=c) _asm mov onechar,10000000b; if(n1=d) asm mov onechar,01000000b; if(n2=a) _asm or onechar,00000000b; if(n2=b) _asm or onechar,00110000b; if(n2=c) _asm or onechar,00100000b; if(n2=d) _asm or onechar,00010000

37、b; if(n3=a) _asm or onechar,00000000b; if(n3=b) _asm or onechar,00001100b; if(n3=c) _asm or onechar,00001000b; if(n3=d) _asm or onechar,00000100b; if(n4=a) _asm or onechar,00000000b; if(n4=b) _asm or onechar,00000011b; if(n4=c) _asm or onechar,00000010b; if(n4=d) _asm or onechar,00000001b; return on

38、echar; ; void linshih3manage(char ptr)/进来字符存起来 每四个存一个 linshih3linshih3number=ptr; linshih3number+; if(linshih3number=4) yasuohuancunyasuohuancunnumber=h3setonechar(linshih30,linshih31,linshih3 2,linshih33); linshih3number=0; yasuohuancunnumber+; ; void writesign(tree fun,int permitnumber,char k,int

39、futhernumber)/先给 sign 的值 递归构建霍夫曼树 if(futhernumber=-1)signpermitnumber=; else signpermitnumber=signfuthernumber+k; / coutsignpermitnumber ; if(funpermitnumber.myzifunumber=0)writesign(fun,funpermitnumber.rightsonn umber,c,permitnumber); if(funpermitnumber.middlesonnumber=0)writesign(fun,funpermitnumb

40、er.middle sonnumber,b,permitnumber); if(funpermitnumber.leftsonnumber=0)writesign(fun,funpermitnumber.leftsonnu mber,a,permitnumber); ; void hafuman3()/三元霍夫曼编码函数 coutuse 3 leaves hafman treeendl; /*电脑明明是 0、1 二元码偏偏用 3元编码 只能用两位二元码表示一 位三元码 但这样本来压缩效率挺高的三元霍夫曼编码竟然不如二元霍夫曼 真是醉了 三元霍夫曼编码一开始 的叶子节点数 一定要满足 2n+3

41、的特点 这个最后还是要处理 三元 则 sign 分别用 0 1 2 表示三元后的编码 */ / int familynumber;/ 记录有多少组父亲、儿子节点记录 int x;/ 常规变量 int h3number=number;/初始叶子数 int begin=0; char h3zifumax; for(x=0;xnumber;x+) h3zifux=zifux; tree h3treemax; for(x=0;xh3number;x+)/ 初始化叶子节点 h3treex.set(everyzifunumberx,-1,-1,-1,x); / count(h3tree,0,h3numbe

42、r); / for(x=0;xh3number;x+) / / couth3zifuh3treex.myzifunumber 次 数 : h3treex.mynumberendl; / while(beginh3number-1)/这里注意 最后一次实际上 begin 是在里面 与 h3number 相等 count(h3tree,begin,h3number); cout *endl; 次数: couth3zifuh3treex.myzifunumber / for(x=begin;xh3number;x+) / / h3treex.mynumberendl; / coutbegin: be

43、gin h3treeh3number.set(h3treebegin.mynumber+h3treebegin+1.mynumber+h3treeb egin+2.mynumber,begin,begin+1,begin+2,-1); couth3treeh3number.leftsonnumber h3treeh3number.middlesonnumber h3treeh3number.rightsonnumberendl; begin=begin+3; couth3numberendl; h3number+; / couth3numberendl; writesign(h3tree,h3

44、number-1,a,-1); couth3numberendl; for(x=0;xh3number;x+) cout 次 数 h3treex.mynumber signxendl; cout 原 字 符 编 码 endl; int t=0; for(x=0;x=0) couth3zifuh3treex.myzifunumber 次 数 h3treex.mynumber signxendl; paixusignt=signx; paixuzifut=h3zifuh3treex.myzifunumber; t+; coutnumber of zifu:tendl; ; void codeman

45、age()/对整个缓存进行编码 coutin code manage programendl; cout字符 压缩字符 endl; int x,i,y; for(x=0;xnumber;x+) coutpaixuzifux paixusignxendl; for(x=0;xhuancunnumber;x+) /cout 正在处理 :huancunx ; i=checkhuancun(x); / coutpaixuzifui=paixuzifui ; for(y=0;ypaixusigni.length();y+) / coutpaixusigniy; linshih3manage(paixus

46、igniy);/ 注意这里有点二维数组的 感觉 / coutendl; if(linshih3number!=0)/补齐一个 char型 8 位最后几位 int tt; for(tt=linshih3number;tt4;tt+) linshih3tt=d; yasuohuancunyasuohuancunnumber=h3setonechar(linshih30,linshih31,linshih3 2,linshih33); linshih3number=0; yasuohuancunnumber+; ; bool checkh3code(string ptr)/对解压缩后的码串译码 in

47、t x; /couti want find ptr; for(x=0;xnumber;x+) if(ptr=paixusignx)/ 这里 string 又可以用“ =”来比较了? 不是 .equal()吗? coutfind x paixusignx paixuzifuxendl; yasuohuancunyasuohuancunnumber=paixuzifux; yasuohuancunnumber+; return true; return false; /coutno find waitingendl; ; void jiemah3code(char ptr)/对一个 char型8位

48、进行解码为 4个 char型 char pp=ptr; char n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15;/n13 n14 n15 没用 _asm mov n1,00h; mov n2,11000000b; mov n3,10000000b; mov n4,00h; mov n5,00110000b; mov n6,00100000b; mov n7,00h; mov n8,00001100b; mov n9,00001000b; mov n10,00h; mov n11,00000011b; mov n12,00000010b;

49、mov n13,00010000b; mov n14,00000100b; mov n15,00000001b; and pp,11000000b; if(pp=n1) linshih30=a; if(pp=n2) linshih30=b; if(pp=n3) linshih30=c; pp=ptr; _asm and pp,00110000b; if(pp=n4) linshih31=a; if(pp=n5) linshih31=b; if(pp=n6) linshih31=c; if(pp=n13) linshih31=d; pp=ptr; _asm and pp,00001100b; i

50、f(pp=n7) linshih32=a; if(pp=n8) linshih32=b; if(pp=n9) linshih32=c; if(pp=n14) linshih32=d; pp=ptr; _asm and pp,00000011b; if(pp=n10) linshih33=a; if(pp=n11) linshih33=b; if(pp=n12) linshih33=c; if(pp=n15) linshih33=d; 使用 huancun放密文,解压后原文放 ; void discodemanage()/解/ 压缩程序 在 yasuohuancun中 / 文件开始的对应表读进

51、paixusign 和 paixuzifu 中 /还要使用 linshih3 coutenter in discode manage programendl; yasuohuancunnumber=0; string holdptr=; int x,y; for(x=0;xhuancunnumber;x+) jiemah3code(huancunx); for(y=0;y4;y+) holdptr=holdptr+linshih3y; if(checkh3code(holdptr) holdptr=; ; char linshih34;/ 临时三元霍夫曼 int linshih3number;

52、/ 记录临时三元霍夫曼个数 int number;/未压缩字符的数量 int everyzifunumbermax;/ 每个字符出现的次数 string signmax;/ 压缩后的字符 (先用数字表示 ) string paixusignmax;/编码后与 paxu 字符数组对应的编码 char paixuzifumax;/ 和字符数组一样,顺序对应 paixusign char zifumax;/未压缩的字符 (互不相同 ) ; void readfile(const char* realfile)/ 文件读入缓存 huancunnumber=0; ifstream inputfile;

53、inputfile.open(realfile); if(!inputfile) coutno fileendl; long int x=0; char a; while(!inputfile.eof() a=inputfile.get(); huancunhuancunnumber=a; huancunnumber+; / couthuancunnumber ; for(x=0;xhuancunnumber;x+) couthuancunx; coutendl; inputfile.close(); void writefile(const char*yasuofile)/ 缓存写入文件 o

54、fstream outputfile; outputfile.open(yasuofile); long int x; for(x=0;xyasuohuancunnumber;x+) outputfileyasuohuancunx; outputfile.close(); int main() readfile(realfile); / writefile(yasuofile); table mytable; mytable.cutrealfile(); mytable.hafuman3(); mytable.codemanage(); writefile(yasuofile); readfi

55、le(yasuofile); mytable.discodemanage(); writefile(jieyasuofile); coutendl; /* char a; _asm mov a,1ah; and a,00h; or a,00011010b couta=aendl; */ return 0; Math (纯净版) .cpp /* 基本要求:对任意输入字符串进行进行自适应算术编码 */ #include #include #include #include #include using namespace std; const char* realfile=n77.bmp;/ 原文

56、件 const char* yasuofile=n3.bmp;/压缩文件 const char* jieyasuofile=n4.bmp;/ 解压缩文件 const int max=10000; char huancunmax;/从文件中读入的字符 char yasuohuancunmax;/压/ 缩后可以写进文件中的字符串 long int yasuohuancunnumber=0;/准/ 备写入文件中的个数 long int huancunnumber=0;/从文件中读出字符个数 class posible_8/lowposible highposible 在这里先通过 getint()

57、转化为 8 位整数再变 成 4 个 2 位的整数方便计算 public:posible_8(); void set(int i) int x,y; for(x=0;x4;x+) y=i/100; every2bit3-x=i-y*100; i=i/100; /* cout for(x=0;x4;x+) coutevery2bitx cout */ int getlong()/得到 every2bit 的小数位长 if(every2bit3=0) if(every2bit2=0) if(every2bit1=0) if(every2bit0=0) return 0; else if(every2

58、bit0-(every2bit0/10)*10)return 2; else return 1; else if(every2bit1-(every2bit1/10)*10)return 4; else return 3; else if(every2bit2-(every2bit2/10)*10)return 6; else return 5; else if(every2bit3-(every2bit3/10)*10)return 8; else return 7; int every2bit4; ; class mathmatic public: mathmatic() highnumb

59、er=0; lownumber=0; lengthnumber=0; number=0; ; void cutrealfile()/ 将缓存中一样的字符区别开 int x; for(x=0;xhuancunnumber;x+) if(check(huancunx)/ 如果是不一样的字符则存进 zifu 数组 zifunumber=huancunx; everyzifunumbernumber=1; number+; for(x=0;xnumber;x+) posiblex=double(everyzifunumberx)/double(huancunnumber); coutzifuendl;

60、 for(x=0;xnumber;x+) coutzifux 次 数 : everyzifunumberx 率 :posiblex ; coutendlnumber=numberendl; ; bool check(char huancun) int x; for(x=0;xnumber;x+) if(zifux=huancun) everyzifunumberx+; return false; return true; ; double getlowposible(char huancun)/得/ 到给出字符的 low 概率区间 int x; double y=0; for(x=0;xnum

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论