/*head1.h*/
#ifndef HEAD1_H_INCLUDED
#define HEAD1_H_INCLUDED
#include
#include
#include
#include
#include
压缩过程 输入:yuandoc.txt 输出:date2.txt
/*
原理:
if 前i个字符是周期性的
then i-next[i]==T[next[i]]
else T[i]=i;
*/
/*
Huffman树
功能:
将TXT文本压缩
1.处理文件后计算字符编码权值
2.构建编码树
3.将字符串转化为编码
4.存储赫夫曼编码树
5.将编码转化为字符串
时间:2018-9-30日 14:05
*/
#include"head1.h"
struct _Date
{
int cc;
int cnt;
} ;
class HuffmanTree
{
public:
int charsize;//字符种类数
int ilen;//读入信息的整形数组大小
int *read_intArr;//读入整形数组信息
int real_size;//真实信息的字节数
_Date *dateArr;//字符表(字符种类 已经对应出现的次数)
HTnode *hufArr;//赫夫曼数组
char **charCodeArr;//每类字符对应的编码
int Allcodesize;//压缩后的bit位数目(因为可能不足一个字节要补成一个字节)
char *codebitArr;
HuffmanTree(char *str,int info_size)
{
/*
需要:读入信息
结果:输出字母表dateArr,记下原文件的字节数real_size,读入文件经过处理后的处理文件read_intArr,共ilen*4个字节,得到字符种类数charsize,
*/
char *read_str;
real_size=info_size;
hufArr=NULL;
charCodeArr=NULL;
codebitArr=NULL;
ilen=info_size/4+(bool)(info_size%4);
read_intArr=new int[ilen+2];
read_str=(char*)read_intArr;
for(int i=0; immp;
map::iterator it;
for(int i=0; i(read_intArr[i],1));
else
it->second++;
}
charsize=mmp.size();
printf("charsize=%d\n",charsize);
dateArr=new _Date[charsize];
int top=0;
for(it=mmp.begin(); it!=mmp.end(); ++it)
{
dateArr[top].cc=it->first;
dateArr[top++].cnt=it->second;
}
mmp.clear();
/*
计算字符串种类以及出现个数 存到dateArr数组里面 共charsize个ok //下标从0开始
*/
}
void BulidTree()
{
/*
需要:字符表,字符个数,
输出:哈夫曼数组,
*/
hufArr=new HTnode[2*charsize-1];
multisethufset;
for(int i=0; i::iterator it;
while(top!=2*charsize-1)
{
it=hufset.begin();
lc=it->index;
hufset.erase(it);
it=hufset.begin();
rc=it->index;
hufset.erase(it);
hufArr[top].lchild=lc;
hufArr[top].rchild=rc;
hufArr[top].weight=hufArr[lc].weight+hufArr[rc].weight;
hufArr[top].index=top;
hufArr[lc].parent=top;
hufArr[rc].parent=top;
hufset.insert(hufArr[top]);
top++;
}
/*
二叉树构建完成
数组为hufArr 根节点为2*charsize-2
对应的字符在dateArr.cc里面
*/
}
void Getcharcode()
{
/*
需要:哈夫曼节点数组hufArr[],字符表种类数charsize
输出:字符对应的编码 存到charcodeArr[][]
*/
charCodeArr=new char*[charsize];
char *midc=new char[charsize+1];//作为中间字符串
int top,now_node,next_node;
Allcodesize=0;
for(int i=0; immp;//字符 对应索引
for(int i=0;i(dateArr[i].cc,i));
}
map::iterator it;
for(int i=0; isecond;
int j=0;
//将此字符对应的编码存储到codebitArr数组中
while(charCodeArr[index][j])
{
++top;
Getbitpos(top,sizepos,bitpos);
// printf("top=%d,sizepos=%d,bitos=%d\n",top,sizepos,bitpos);
if(charCodeArr[index][j]=='0')
{
evalubit(&codebitArr[sizepos-1],bitpos,0);
}
else
{
evalubit(&codebitArr[sizepos-1],bitpos,1);
}
j++;
}
}
mmp.clear();
while(top
解压代码 输入date2.txt 输出info.txt
/*
解压程序
*/
#include"head1.h"
void Compress_file(FILE *fp)//对文件进行解压 当成解压字符ASSIC码并存到文本里面(二进制存储)
{
int charsize,Allcodesize,real_size,info_size;
int sizepos,bitpos,now_index;
char *codebitArr;
int *InfoArr;//来存储解码后的信息
TireNode *tirenode;
int mid;
fread(&charsize,4,1,fp);//读取 charsize
fread(&Allcodesize,4,1,fp);//读取 有用的编码位数
fread(&real_size,4,1,fp);//读取 真正的字节数目
fread(&info_size,4,1,fp);//读取 压缩的int个数
mid=Allcodesize/8;
if(Allcodesize%8)
mid++;
tirenode=new TireNode[2*charsize-1];
codebitArr=new char[mid];//申请编码内存
fread(tirenode,sizeof(TireNode),charsize*2-1,fp);//读取哈夫曼树
fread(codebitArr,1,mid,fp);//读取编码
int top=0;
int cnt=0;
now_index=2*charsize-2;
InfoArr=new int[info_size];
while(top