文件压缩程序设计报告.docx
- 文档编号:5086813
- 上传时间:2022-12-13
- 格式:DOCX
- 页数:27
- 大小:197.90KB
文件压缩程序设计报告.docx
《文件压缩程序设计报告.docx》由会员分享,可在线阅读,更多相关《文件压缩程序设计报告.docx(27页珍藏版)》请在冰豆网上搜索。
文件压缩程序设计报告
课程设计报告
课程名称:
操作系统
实验题目:
文件压缩程序
院系:
计算机科学与工程学院
班级:
姓名:
学号:
二○一一年七月一日
一、需求分析:
有两种形式的重复存在于计算机数据中,文件压缩程序就是对这两种重复进行了压缩。
一种是短语形式的重复,即三个字节以上的重复,对于这种重复,压缩程序用两个数字:
1.重复位置距当前压缩位置的距离;2.重复的长度,来表示这个重复,假设这两个数字各占一个字节,于是数据便得到了压缩。
第二种重复为单字节的重复,一个字节只有256种可能的取值,所以这种重复是必然的。
给256种字节取值重新编码,使出现较多的字节使用较短的编码,出现较少的字节使用较长的编码,这样一来,变短的字节相对于变长的字节更多,文件的总长度就会减少,并且,字节使用比例越不均匀,压缩比例就越大。
编码式压缩必须在短语式压缩之后进行,因为编码式压缩后,原先八位二进制值的字节就被破坏了,这样文件中短语式重复的倾向也会被破坏(除非先进行解码)。
另外,短语式压缩后的结果:
那些剩下的未被匹配的单、双字节和得到匹配的距离、长度值仍然具有取值分布不均匀性,因此,两种压缩方式的顺序不能变。
本程序设计只做了编码式压缩,采用Huffman编码进行压缩和解压缩。
Huffman编码是一种可变长编码方式,是二叉树的一种特殊转化形式。
编码的原理是:
将使用次数多的代码转换成长度较短的代码,而使用次数少的可以使用较长的编码,并且保持编码的唯一可解性。
根据ascii码文件中各ascii字符出现的频率情况创建Huffman树,再将各字符对应的哈夫曼编码写入文件中。
同时,亦可根据对应的哈夫曼树,将哈夫曼编码文件解压成字符文件.
二、概要设计:
主程序流程图:
主函数
统计字符,得出统计出的字符的权值n
编码
解码
退出
根据权值进行建立Huffman树
输出Huffman树
输出编码
压缩编码
生成压缩文件
解压
生成新的文本文档
扫描压缩文件,载入字符信息
根据权值进行建立Huffman树
输出Huffman树
测试
输入测试字符串
统计字符信息,建立Huffman曼树
根据Huffman树,求得对应字符的Huffman编码
输入Huffman编码,求得解码
压缩过程的实现:
压缩过程的流程是清晰而简单的:
1.创建Huffman树
2.打开需压缩文件
3.将需压缩文件中的每个ascii码对应的huffman编码按bit单位输出生成压缩文件压缩结束。
其中,步骤1和步骤3是压缩过程的关键。
步骤1:
这里所要做工作是得到Huffman数中各叶子结点字符出现的频率并进行创建.统计字符出现的频率可以有很多方法:
如每次创建前扫描被创建的文件,“实时”的生成各字符的出现频率;或者是创建前即做好统计.这里采用的是前一种方法。
步骤3:
将需压缩文件中的每个ascii码对应的huffman编码按bit单位输出.
这是本压缩程序中最关键的部分:
这里涉及“转换”和“输出”两个关键步骤:
“转换”部分大可不必去通过遍历Huffman树来找到每个字符对应的哈夫曼编码,可以将每个Huffman码值及其对应的ascii码存放于如下所示的结
构体中:
解压缩过程的实现:
如果说,压缩的过程可以通过查找codeList来加速实现的话,而解压缩则必须通过查找huffman树才能加以实现.查找的过程是简单的,可以根据
huffman树的性质来做,当haffCode的当前bit位为0时,则向左枝展开搜索;当前bit位为1时,则向右枝展开搜索,当遇到叶子结点时,则输出haffCode对应的asciiCode。
三、详细设计:
核心算法源程序:
Huffman树建立源程序:
//-------------------------------------------------------------
//huffmantree.h
//霍夫曼树
#ifndefHUFFMANTREE
#defineHUFFMANTREE
#defineDefaultsize300
#include
#include"bintree.h"
#include"heap.h"
classCode
{
public:
intcode;
Code*link;
Code(intc=0,Code*l=NULL):
code(c),link(l){};
};
classCharNameNode
{
public:
unsignedcharcharname;//要这样才行
Code*link;
CharNameNode(unsignedcharc=0,Code*l=NULL):
charname(c),link(l){};
};
template
classHuffmanTree:
publicBinaryTree
{
public:
intkey;
HuffmanTree(){};
HuffmanTree(HuffmanTree
{
Typetemp=0;//可能有变
key=ht1.key+ht2.key;
root=newBinTreeNode
}
voidBuild(int*fr,Type*value,intn,HuffmanTree
voidPath(BinTreeNode
};
template
voidHuffmanTree
:
Build(int*fr,Type*value,intn,HuffmanTree
{//fr为 value(值) 对应的权
inti;
HuffmanTree
HuffmanTree
MinHeap
assert(n>=0&&n<=Defaultsize);
for(i=0;i { Node[i].root=newBinTreeNode Node[i].key=fr[i]; } hp=MinHeap for(i=0;i { hp.RemoveMin(first); hp.RemoveMin(second); HuffmanTree hp.Insert(*temp); } hp.RemoveMin(newtree); } template voidHuffmanTree : Path(BinTreeNode { if(start==NULL) return; //if(start->GetData()! =0)//是叶结点严重错误,可能叶结点也是0! ! if(start->GetLeft()==NULL&&start->GetRight()==NULL) { Node[i].charname=start->GetData(); Node[i].link=NULL; if(first==NULL) return; Node[i].link=newCode(first->code); Code*p=first->link,*q=Node[i].link; while(p! =NULL) { q->link=newCode(p->code); q=q->link; p=p->link; } q->link=NULL; i++; return; } Code*temp=newCode;//进入左子树 assert(temp); if(first==NULL) first=last=temp; else { last->link=temp; last=last->link; } Path(start->GetLeft(),first,last,Node,i); last->code=1; Path(start->GetRight(),first,last,Node,i); temp=first; if(first==last) { deletelast; first=last=NULL; return; } while(temp->link! =last) temp=temp->link; temp->link=NULL; deletelast; last=temp; } #endif 实现二叉树的算法源程序: //--------------------------------------------------------------------- //bintree.h //用指针实现的二叉树 //Type类型必须有重载<<与>>及=运算 #ifndefBINTREE #defineBINTREE #include #include intMax(inta,intb) { returna>b? a: b; } template classBinaryTree; template classBinTreeNode { friendclassBinaryTree public: BinTreeNode(): leftchild(NULL),rightchild(NULL){}; BinTreeNode(Typeitem,BinTreeNode : data(item),leftchild(left),rightchild(right){}; TypeGetData()const{returndata;} BinTreeNode BinTreeNode voidSetData(constType&item){data=item;} voidSetLeft(BinTreeNode voidSetRight(BinTreeNode private: BinTreeNode Typedata; }; template classBinaryTree { public: BinaryTree(): root(NULL){}; BinaryTree(constBinaryTree BinaryTree(constType&temp,constBinaryTree BinaryTree(Typevalue): RefValue(value),root(NULL){}; voidoperator=(constBinaryTree virtual~BinaryTree(){Destroy(root);} voidDestroy(){Destroy(root);root=NULL;} virtualintIsEmpty(){returnroot==NULL? 1: 0;} virtualBinTreeNode { returnroot==NULL||root==current? NULL: Parent(root,current); } virtualBinTreeNode { returnroot! =NULL? current->leftchild: NULL; } virtualBinTreeNode { returnroot! =NULL? current->rightchild: NULL; } virtualintInsert(constType&item); virtualintFind(constType&item)const; BinTreeNode friendintEqual(BinTreeNode friendintoperator==(constBinaryTree friendistream&operator>>(istream&in,BinaryTree friendostream&operator<<(ostream&out,BinaryTree voidInOrder();//遍历 voidPreOrder(); voidPostOrder(); //******************************************//一些应用 intSize(){returnSize(root);}//统计结点数 intDepth(){returnDepth(root);}//计算树的深度 intLeaves(){returnLeaves(root);} intDegrees1(){returnDegrees1(root);} intDegrees2(){returnDegrees2(root);} protected: BinTreeNode TypeRefValue; BinTreeNode intInsert(BinTreeNode intFind(BinTreeNode BinTreeNode voidDestroy(BinTreeNode //****************************************** voidInOrder(BinTreeNode voidPreOrder(BinTreeNode voidPostOrder(BinTreeNode //******************************************//一些应用 intSize(constBinTreeNode intDepth(constBinTreeNode intLeaves(constBinTreeNode intDegrees1(constBinTreeNode intDegrees2(constBinTreeNode }; template BinTreeNode : Copy(BinTreeNode { if(orignode==NULL) returnNULL; BinTreeNode temp->data=orignode->data; temp->leftchild=Copy(orignode->leftchild); temp->rightchild=Copy(orignode->rightchild); returntemp; } template BinaryTree : BinaryTree(constType&temp,constBinaryTree { root=newBinTreeNode } template voidBinaryTree : operator=(constBinaryTree { Destroy(); //Destroy(root);root=NULL;//为什么要这样? ? ? root=Copy(bt1.root); } template voidBinaryTree : Destroy(BinTreeNode { if(current! =NULL) { Destroy(current->leftchild); Destroy(current->rightchild); deletecurrent; } } template BinTreeNode : Parent(BinTreeNode { if(start==NULL)returnNULL; if(start->leftchild==current||start->rightchild==current) returnstart; BinTreeNode if((p=Parent(start->leftchild,current))! =NULL)//在start的左子树中找 returnp; else returnParent(start->rightchild,current); } template intBinaryTree : Insert(BinTreeNode { if(current==NULL) return0; BinTreeNode if(current->leftchild==NULL) current->leftchild=p; elseif(current->rightchild==NULL) current->rightchild=p; else Insert(current->leftchild,item);//这样插可是构不成树状的! 估且一用吧 return1; } template intBinaryTree : Insert(constType&item) { if(root==NULL) { root=newBinTreeNode return1; } returnInsert(root,item); } template intBinaryTree : Find(BinTreeNode { if(current==NULL) return0; if(current->data==item) return1; intk; if((k=Find(current->leftchild,item))! =0) return1; else returnFind(current->rightchild,item); } template intBinaryTree : Find(constType&item)const { returnFind(root,item); } template intEqual(BinTreeNode
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 文件 压缩 程序设计 报告