算法设计与分析课程设计报告.docx
- 文档编号:27446218
- 上传时间:2023-07-01
- 格式:DOCX
- 页数:14
- 大小:194.25KB
算法设计与分析课程设计报告.docx
《算法设计与分析课程设计报告.docx》由会员分享,可在线阅读,更多相关《算法设计与分析课程设计报告.docx(14页珍藏版)》请在冰豆网上搜索。
算法设计与分析课程设计报告
压缩软件课程设计书
一、问题描述:
建立一个文本文件,统计该文件中各字符频率,对各字符进行Huffman编码,将该文件至翻译成Huffman编码文件,再将Huffman编码文件翻译成原文件。
二、算法分析及思路:
对于该问题,我们做如下分析:
(1)首先得构造出哈弗曼树,我们用函数HuffmanTree(intw[],ints[],intn)设计;
(2)在构建哈弗曼树的基础上,进一步实现哈弗曼编码问题,我们用函数Huffmancode(charwen[])设计;
(3)实现哈弗曼编码后再进一步实现哈弗曼译码问题,我们用函数Huffmandecode()设计;
(4)其中编码问题中,得进一步统计出各个字符在文件中的频率,并进行一些必要的标记,我们用函数runhuffman(charwen[])设计;
(5)在译码过程中,还有必要的一步是比较原文件与译码后的文件是否相同,我们用函数compare(charwen[])设计;
(6)其中的文件输入我们用到类”fstream.h”中的输入输出流,并在运行的文件夹中建立一个文件名为逍遥游的文本文件,且在逍遥游文件中输入需要编码的数据。
三、主要解决的设计问题:
1.写一个对txt文件压缩和解压的程序,使用动态编码。
2.使用Huffman编码压缩和解压时,Huffman树的存储可以直接存储树结构,也可以存储所有字符的频度或权值,然后读取时建立Huffman树;
3.使用Huffman编码压缩和解压时,注意定义压缩码的结束标记,可以使用一个特殊的字符作为结束标记,也可以在压缩码之前存储其比特长度;如果使用一个特殊字符作为结束标记,则其频度为1,需要在建立Huffman树时把它看作一个独立的字符进行建树。
4.使用Huffman编码压缩和解压时,在一个缓冲区里面收集压缩码比特流,每当收集的比特数满8时,可以把这8比特通过位操作合并成一个字节写入文件(当然也可以收集满一定数目的字节后再写入文件)。
写入文件的最小信息单位为字节。
四、程序设计的流程图:
五、输入和输出说明:
1、数据输入:
由文件input.txt提供输入需要压缩的内容;
2、结果输出:
将压缩好的文件内容输出到《编码后的文件.txt》中,再由《编码后的文件.txt》解压到《译码后的文件.txt》中。
六、程序及其注解:
1、数据结构设计(即类的设计,包括类的数据成员、函数成员)
类的设计用HuffmanTree.h保存如下:
#include
#include
usingnamespacestd;
constintMaxSize=512;
//--------------------------------------------------------------
structelement//哈夫曼树的结点
{
intstr;//记录字符在数组中的位置
intweight;//字符出现频率(权值)
intlchild,rchild,parent;//哈夫曼树各个指针变量
charbits[30];//存储哈夫曼编码的数组
};
//--------------------------------------------------------------
classHuffmanTree
{
elementhufftree[MaxSize];//存放哈夫曼树结点的数组
intnum;//结点数
public:
HuffmanTree(intw[],ints[],intn);
voidSelect(intn,int&s1,int&s2);
voidHuffmancode(charwen[]);//哈夫曼编码
voidHuffmandecode();//哈夫曼译码
};
//--------------------------------------------------------------
classRun
{
public:
voidhuffman(charwen[]);//将编码后的文件译成原文件
voidrunhuffman(charwen[]);//统计各字符频率
voidcompare(charwen[]);//比较逍遥游文件和译码后的文件
};
//--------------------------------------------------------------
2、算法设计(类的函数成员的具体设计)
(1)算法一设计用HuffmanTree.cpp保存如下:
#include
#include"HuffmanTree.h"
usingnamespacestd;
//-------------------------------------------------------------------
voidHuffmanTree:
:
Select(intn,int&s1,int&s2)
{
s1=-1;
s2=-1;
for(inti=0;i<=n;i++)
{
if(hufftree[i].parent==-1)
{
if(s1==-1){s1=i;continue;}
if(s2==-1){s2=i;continue;}
if(hufftree[i].weight s1=i; elseif(hufftree[i].weight s2=i; } } } //------------------------------------------------------------------- HuffmanTree: : HuffmanTree(intw[],ints[],intn) { num=n; inti1,i2; i1=i2=0; for(inti=0;i<2*num-1;i++)//外部叶子结点数为num个时,内部结点数为n-1,整个哈夫曼树的需要的结点数为2*num-1. { hufftree[i].parent=-1; hufftree[i].lchild=-1; hufftree[i].rchild=-1; } for(intj=0;j { hufftree[j].weight=w[j]; hufftree[j].str=s[j]; } for(intk=num;k<2*num-1;k++)//构建哈夫曼树 { Select(k-1,i1,i2);//在hufftree中找权值最小的两个结点i1和i2 hufftree[i1].parent=k; hufftree[i2].parent=k; hufftree[k].weight=hufftree[i1].weight+hufftree[i2].weight; hufftree[k].lchild=i1; hufftree[k].rchild=i2; } } //------------------------------------------------------------------- voidHuffmanTree: : Huffmancode(charwen[]) { ifstreamin(wen); ofstreamout("编码后的文件.txt"); intstart=MaxSize-1; intcha=0; charcd[MaxSize];//存放一个编码 cd[MaxSize-1]='\0'; for(inti=0;i { start=MaxSize-1; intc,f; for(c=i,f=hufftree[i].parent;f! =-1;c=f,f=hufftree[f].parent) { if(hufftree[f].lchild==c)//置左分支编码0 cd[--start]='0'; elsecd[--start]='1';//置右分支编码1 } strcpy(hufftree[i].bits,&cd[start]);//将编码存放在相应结点存储哈夫曼编码的数组中 } cout<<"字符在数组中的下标及其编码如下: ";//输出字符在数组中的位置及其编码 for(intk=0;k { if(k%3==0)cout< cout< "< } cout< for(charch;in.get(ch);)//将逍遥游文件中各个字符转变成相应的编码,写入编码后的文件中 { if((int)ch<0)cha=(int)ch+256; elsecha=(int)ch; for(intj=0;j if(hufftree[j].str==cha) out< } cout<<"编码成功! "< } //------------------------------------------------------------------- voidHuffmanTree: : Huffmandecode() { ifstreamin("编码后的文件.txt"); ofstreamout("译码后的文件.txt"); inti=2*num-2; for(charb;in>>b;) { if(b=='0')i=hufftree[i].lchild; elsei=hufftree[i].rchild; if(hufftree[i].lchild==-1) { out<<(char)hufftree[i].str; i=2*num-2; } } cout<<"译码成功! "< } //------------------------------------------------------------------- (2)算法二设计用HuffmanRun.cpp保存如下: #include #include"HuffmanTree.h" usingnamespacestd; //--------------------------------------------------------- voidRun: : runhuffman(charwen[]) { ifstreamin(wen); intw[MaxSize]; intweight[MaxSize];//存放各个字符的频率 intstr[MaxSize];//存放逍遥游文件中各个字符在数组w中的位置(下标) inti=0; intn=0; intcha=0; for(intj=0;j w[j]=0; /*从文件逍遥游中依次读入字符,根据字符的ASCII码值将字符存入str[]数组的相应位置 而weight[]数组的相应位置则记录该字符出现的频率*/ for(charch;in.get(ch);) { if((int)ch<0)cha=(int)ch+256;//中文的ASCII码值为负数,加上256使其可以存放在数组中 elsecha=(int)ch; w[cha]++; } for(intk=0;k if(w[k]! =0) { str[n]=k; weight[n]=w[k]; n++; } cout<<"字符在数组中的下标及其权值如下: ";//输出字符在数组中的位置及其权值 for(intp=0;p { if(p%6==0) cout< cout< "< } cout< HuffmanTreeh(weight,str,n);//构造哈夫曼树 h.Huffmancode(wen);//利用哈夫曼树进行编码及译码 h.Huffmandecode(); } //--------------------------------------------------------- voidRun: : huffman(charwen[]) { ifstreamin(wen); intweight[MaxSize];//存放各个字符的频率 intstr[MaxSize];//存放逍遥游文件中各个字符在数组w中的位置(下标) intn=0; HuffmanTreeh(weight,str,n);//构造哈夫曼树 h.Huffmandecode(); } voidRun: : compare(charwen[]) { ifstreamina(wen); ifstreaminc("译码后的文件.txt"); charstringa[100000]; inti=0; intflag=0; charstringc[100000]; intj=0; for(charcha;ina>>cha;)//将文件逍遥游的内容读入数组stringa[] { stringa[i]=cha; i++; } stringa[i]='\0'; for(charchc;inc>>chc;)//将译码后的文件内容读入数组stringc[] { stringc[j]=chc; j++; } stringc[j]='\0'; /*比较文件逍遥游和译码后的文件内容,若相同则说明编码正确,若不同, 则说明编码错误*/ for(intk=0;stringa[k]! ='\0'&&stringc[k]! ='\0';k++) if(stringa[k]! =stringc[k])flag=0; if(stringa[k]=='\0'&&stringc[k]=='\0')flag=1; elseflag=0; if(flag==0) cout<<"逍遥游文件与译码后的文件不相同,编码错误! "< else cout<<"逍遥游文件与译码后的文件相同,编码正确! "< } //--------------------------------------------------------- (3)实现算法设计的主程序用HaffmanMain.cpp保存如下: #include #include"HuffmanTree.h" usingnamespacestd; voidmain() { charwenjian[20];intt=1; while (1) { if(t==1) {cout<<"请输入要编码的文件名: "; cin>>wenjian; Runmanager; manager.runhuffman(wenjian); pare(wenjian);} else {cout<<"请输入要译码的文件名: "; cin>>wenjian; Runmanager; manager.huffman(wenjian);} cout<<"请继续选择需要执行的功能: "< cout<<"请问您是需要编码文件还是译码文件? "< cout<<"如果是要编码文件,那么请输入1;"< cout<<"如果是要译码文件,那么请输入0。 "< cin>>t; } } 七、程序运行结果及分析: 该课程设计实现了哈弗曼编码及译码问题,其中有一些独到之处,同时也有很多不足之处。 比如说: 其中的由编码文件直接翻译成译码文件没有单独实现,也没有很好的算法直接描述,而正好该问题在实际用途中很广泛,一般都要由一些特定规则单独实现译码问题。 希望在以后的进一步学习中能很好的掌握该问题的算法优化。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 设计 分析 课程设计 报告