基于哈夫曼编码实现文本文件的压缩和解压缩.docx
《基于哈夫曼编码实现文本文件的压缩和解压缩.docx》由会员分享,可在线阅读,更多相关《基于哈夫曼编码实现文本文件的压缩和解压缩.docx(15页珍藏版)》请在冰豆网上搜索。
基于哈夫曼编码实现文本文件的压缩和解压缩
#include
#include
#ifndef_UNISTD_H
#define_UNISTD_H
#include
#include
#endif/*_UNISTD_H*/
#include
#include
#include
#include
#include
#include
#include
usingnamespacestd;
typedefstruct
{
intweight;
intparent,lchild,rchild;
}HTNode,*HuffmanTree;
typedefstruct
{
char*data;
int*num;
intlength;
}TNode;
typedefstruct
{
char*data;
char**HM;
}Code;
typedefchar**HuffmanCode;
boolIfEncode()
{
intchoose;
system("color70");
cout<<"\t1.加密压缩2.无密压缩"<cout<<"请输入选择:
";
cin>>choose;
if(choose==1)
returntrue;
else
returnfalse;
}
voidEncode(vector&v)
{
charch[30];
v.push_back('@');
system("color70");
cout<<"请输入压缩密码"<cin>>ch;
for(inti=0;ch[i]!
='\0';i++)
v.push_back(ch[i]);
v.push_back('\0');
v.push_back('@');
cout<<"开始压缩!
"<}
voidReadTxt(vector&v)
{
charch;
ifstreaminfile("test.txt",ios:
:
in);
if(!
infile)
{
cerr<<"openerror"<exit
(1);
}
if(IfEncode())
Encode(v);
while(infile.peek()!
=EOF)
{
infile.get(ch);
v.push_back(ch);
}
infile.close();
}
voidInitList(TNode&T)
{
T.data=newchar[256];
T.num=newint[256];
if(!
T.data||!
T.num)
exit
(1);
T.length=0;
}
boolFind(TNodeT,charch)
{
inti;
for(i=0;iif(ch==T.data[i])
returntrue;
returnfalse;
}
voidTCount(vectorv1,TNode&T)
{
inti,j=0;
charch;
intm=v1.size();
for(i=0;i{
ch=v1[i];
if(!
Find(T,ch))
{
T.data[j]=ch;
T.num[j]=count(v1.begin(),v1.end(),ch);
j++;
T.length++;
}
}
}
voidSelect(HuffmanTree&HT,intm,int&s1,int&s2)
{
intk,j,n,min=32767;
for(k=1;k<=m;k++)
{
if(HT[k].parent==0)
if(HT[k].weight<=min)
{
j=k;
min=HT[k].weight;
}
}
s1=j;
HT[j].parent=1;
min=32767;
for(k=1;k<=m;k++)
{
if(HT[k].parent==0)
if(HT[k].weight<=min)
{
n=k;
min=HT[k].weight;
}
}
s2=n;
}
voidCreateHuffmanTree(HuffmanTree&HT,TNodeT,intlength)
{
intm,i,s1,s2;
if(length<=1)
return;
m=2*length-1;
HT=newHTNode[m+1];
for(i=1;i<=m;++i)
{
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=1;i<=length;++i)
HT[i].weight=T.num[i-1];
for(i=length+1;i<=m;i++)
{
Select(HT,i-1,s1,s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}
voidCreatHuffmanCode(HuffmanTreeHT,HuffmanCode&HC,intn)
{
inti,f,c,start;
HC=newchar*[n+1];
char*cd=newchar[n];
cd[n-1]='\0';
for(i=1;i<=n;i++)
{
start=n-1;
c=i;
f=HT[i].parent;
while(f!
=0)
{
--start;
if(HT[f].lchild==c)
cd[start]='0';
else
cd[start]='1';
c=f;
f=HT[f].parent;
}
HC[i]=newchar[n-start];
strcpy(HC[i],&cd[start]);
}
deletecd;
}
intgetFileSizeSystemCall(char*strFileName)
{
structstattemp;
stat(strFileName,&temp);
returntemp.st_size;
}
voidZip(HuffmanCodeHC,vectorv,TNodeT)
{
inti=0,j=0,k=0;
ofstreamoutfile("zip.txt",ios:
:
out);
if(!
outfile)
{
cerr<<"openerror"<exit
(1);
}
cout<<"输出哈夫曼编码"<for(i=0;i{
for(j=0;jif(T.data[j]==v[i])
break;
for(k=0;HC[j+1][k]!
='\0';k++)
{cout<for(k=0;HC[j+1][k]!
='\0';k++)
outfile<}
cout<outfile.close();
cout<<"正在压缩。
";Sleep(500);cout<<"。
";Sleep(500);cout<<"。
"<cout<<"压缩成功!
可到zip.txt中查看压缩后文件"<}
boolREncode(charch[])
{
inti=0;
charcode[30];
cout<<"请输入解压密码:
"<cin>>code;
if(strcmp(code,ch)==0)
returntrue;
else
returnfalse;
}
intin_HM(Code&c)
{
c.data=newchar[256];
c.HM=newchar*[256];
intlength=0,i;
ifstreaminfile("code.dat",ios:
:
in);
if(!
infile)
{
cerr<<"openerror"<exit
(1);
}
infile>>length;
for(i=0;i{
infile>>c.data[i];
c.HM[i]=newchar[length+1];
infile>>c.HM[i];
}
infile.close();
returnlength;
}
voidout_HM(HuffmanCodeHC,TNodeT)
{
inti;
ofstreamoutfile("code.dat",ios:
:
out);
if(!
outfile)
{
cerr<<"openerror"<exit
(1);
}
outfile<for(i=0;i{
outfile<outfile<}
outfile.close();
}
voidRZip(HuffmanCodeHC,TNodeT)
{
charch;
charch2[30];
inti,j,flag,flag2=0,m=0;
ofstreamoutfile("rzip.txt",ios:
:
out);
ifstreaminfile("zip.txt",ios:
:
in);
if(!
outfile)
{
cerr<<"openerror"<exit
(1);
}
if(!
infile)
{
cerr<<"openerror"<exit
(1);
}
while(infile.peek()!
=EOF)
{
flag=0;
char*cd=newchar[T.length];
for(i=0;;i++)
{
infile>>ch;
cd[i]=ch;
cd[i+1]='\0';
for(j=1;j<=T.length;j++)
if(strcmp(HC[j],cd)==0)
{
if(T.data[j-1]=='@')
{
if(flag2==0)
{
flag=1;
flag2=1;
deletecd;
break;
}
if(flag2==1)
{
while
(1)
{
if(REncode(ch2))
{
cout<<"密码正确,正在解压!
"<flag2=0;
break;
}
else
cout<<"密码错误,请重新输入"<}
flag=1;
deletecd;
break;
}
}
if(flag2==1)
{
ch2[m]=T.data[j-1];
flag=1;
m++;
deletecd;
break;
}
if(flag2==0)
{
outfile<flag=1;
deletecd;
break;
}
}
if(flag==1)
break;
}
}
cout<<"正在解压。
";Sleep(500);cout<<"。
";Sleep(500);cout<<"。
"<cout<<"解压成功!
请到rzip.txt中查看解压后文件"<}
voidabout()
{
system("cls");
system("color70");
cout<<"\t╔═══════════════════════════════╗"<cout<<"\t║欢迎使用解压缩程序║"<cout<<"\t║关于程序:
║"<cout<<"\t║压缩:
║"<cout<<"\t║默认压缩程序所在目录下的test.txt,生成压缩后的zip.txt║"<cout<<"\t║║"<cout<<"\t║解压:
║"<cout<<"\t║默认解压序所在目录下的zip.txt,生成解压后的rzip.txt║"<cout<<"\t║║"<cout<<"\t║║"<cout<<"\t║程序支持压缩中英文文件。
║"<cout<<"\t║║"<cout<<"\t╚═══════════════════════════════╝"<}
voidmenu()
{
system("color70");
cout<<"\t╔═══════════════════════════════╗"<cout<<"\t║║"<cout<<"\t║欢迎使用解压缩程序║"<cout<<"\t║║"<cout<<"\t║1.压缩文件║"<cout<<"\t║2.解压文件║"<cout<<"\t║3.具体信息║"<cout<<"\t║4.退出程序║"<cout<<"\t║║"<cout<<"\t╚═══════════════════════════════╝"<}
intmain()
{
vectorv;
intn,choose,size1,size2,size3;
TNodeT;
InitList(T);
HuffmanTreeHT;
HuffmanCodeHC;
while
(1)
{
system("cls");
menu();
system("color70");
cout<<"请输入所选择的序号:
";
cin>>choose;
switch(choose)
{
case1:
ReadTxt(v);
TCount(v,T);
n=T.length;
CreateHuffmanTree(HT,T,n);
CreatHuffmanCode(HT,HC,n);
Zip(HC,v,T);
size1=getFileSizeSystemCall("test.txt");
cout<<"原文件中有"<cout<size2=getFileSizeSystemCall("zip.txt");
cout<<"压缩后有"<cout<out_HM(HC,T);
system("pause");
break;
case2:
RZip(HC,T);
size3=getFileSizeSystemCall("rzip.txt");
cout<<"解压缩后有"<cout<system("pause");
break;
case3:
about();
system("pause");
break;
case4:
return0;
default:
system("color70");
cout<<"输入错误!
请重新输入";
system("pause");
break;
}
}
return0;
}