算法设计与分析课程设计报告.docx

上传人:b****3 文档编号:27446218 上传时间:2023-07-01 格式:DOCX 页数:14 大小:194.25KB
下载 相关 举报
算法设计与分析课程设计报告.docx_第1页
第1页 / 共14页
算法设计与分析课程设计报告.docx_第2页
第2页 / 共14页
算法设计与分析课程设计报告.docx_第3页
第3页 / 共14页
算法设计与分析课程设计报告.docx_第4页
第4页 / 共14页
算法设计与分析课程设计报告.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

算法设计与分析课程设计报告.docx

《算法设计与分析课程设计报告.docx》由会员分享,可在线阅读,更多相关《算法设计与分析课程设计报告.docx(14页珍藏版)》请在冰豆网上搜索。

算法设计与分析课程设计报告.docx

算法设计与分析课程设计报告

压缩软件课程设计书

一、问题描述:

建立一个文本文件,统计该文件中各字符频率,对各字符进行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;

}

}

 

七、程序运行结果及分析:

该课程设计实现了哈弗曼编码及译码问题,其中有一些独到之处,同时也有很多不足之处。

比如说:

其中的由编码文件直接翻译成译码文件没有单独实现,也没有很好的算法直接描述,而正好该问题在实际用途中很广泛,一般都要由一些特定规则单独实现译码问题。

希望在以后的进一步学习中能很好的掌握该问题的算法优化。

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

当前位置:首页 > 农林牧渔 > 林学

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

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