📄 text.cpp
字号:
#include "stdafx.h"
#include "Text.h"
#include "BinaryTree.h"
#include "huffman.h"
#define OFFSET 1024
Text::Text()
{
BOOL openfile=0;
NUM=256;
Number=0;
for(int i=0;i<NUM;i++)
frequency[i]=0;
chpath=new char*[256];
t=new BYTE[256];
}
Text::~Text()
{
}
BinaryTree<int>Text :: HuffmanTree( int n)
{
Huffman *w = new Huffman [n+1];
BinaryTree<int> z, zero;
for (int i = 1; i <= n; i++)
{
z.MakeTree(t[i-1], zero, zero);
w[i].weight = frequency[t [i-1]];
w[i].tree = z;
}
// make array into a min heap
MinHeap<Huffman> H(1);
H.Initialize(w,n,n);
// repeatedly combine trees from heap
Huffman x, y;
for (int i = 1; i < n; i++)
{
H.DeleteMin(x);
H.DeleteMin(y);
z.MakeTree(0, x.tree, y.tree);
x.weight += y.weight; x.tree = z;
H.Insert(x);
}
H.DeleteMin(x); // final tree
H.Deactivate();
delete [] w;
return x.tree;
}
void Text::ReadAllFile(CString filename1,CString filename2)
{
const int flag=1;
UINT count;
int number=0;
BYTE bt[OFFSET];
if(readfile.Open((LPCTSTR)filename1, CFile::modeRead ,NULL))
{
while(flag)
{
count=readfile.Read(bt,OFFSET);
for(UINT i=0;i<count;i++)
{
frequency[bt[i]]++;//统计频率
}
if(count!=1024)
break;
}
int k=0;
for(int i=0;i<256;i++)
{
if(frequency[i])
{
t[k++]=i;//获取非零频率所在数组的下标
Number++;//非零下标数目
}
}
for(int k=0,j=0;k<NUM;k++)
{
if(frequency[k])
{
str[j].frequency=frequency[k];
str[j++].code=k;
}
}
}
Huffman huffman;
BinaryTree<int> Btr;
BYTE H;
Btr= HuffmanTree( Number);//构建霍夫曼树
H=(BYTE) Btr.Height();//获取霍夫曼树高度,即编码数组的长度,以分配空间
for(int i=0;i<=256;i++)
chpath[i]=new char[H];
Btr.OuthuffmanTreePath(chpath,Number);//获取霍夫曼编码
writefile.Open((LPCTSTR)filename2,CFile::modeWrite ,NULL);
writefile.SeekToBegin();
writefile.Write(&H,sizeof(BYTE));
writefile.Write(&Number,sizeof(BYTE));
//writefile.Write(&str,sizeof(STR_)*(Number+1));
// writefile.Write(&Number,sizeof(BYTE));
for(int i=0;i<=Number;i++)
{
writefile.Write(&t[i],sizeof(BYTE));
writefile.Write(&frequency[t[i]],sizeof(UINT));
}
UINT WriteByteCount=OFFSET;
BYTE b[OFFSET];
WORD Bitflag=0;
DWORD Bit=0 ;
int flag1=0;
size_t l;
readfile.SeekToBegin();
while(WriteByteCount==OFFSET)
{
WriteByteCount=readfile.Read(b,OFFSET);
for(UINT i=0;i<WriteByteCount;i++)
{
l=strlen(chpath[b[i]]);//huofuman编码,形如1010110
for(size_t k=0;k< l;k++)
{
if(Bitflag==32)
{
writefile.Write(&Bit,sizeof(DWORD));//够三十二位后写文件
Bitflag=0;
Bit =0;
}
Bit=Bit<<1;//转换成DWORD
Bitflag++;
if(chpath[b[i]][k]=='1')
Bit =Bit|1;
}
}
}
if(Bitflag!=32)//不够32位,左移
{
Bit =Bit<<(32-Bitflag);
writefile.Write(&Bit,sizeof(DWORD));
}
}
void Text::OpenPressFile(CString filename1, CString filename2)
{
const int flag=1;
int Flag=0;
BYTE write[256];//写文件是所用的统计数组
DWORD rd[OFFSET/4];
BYTE n,m;
BinaryTree<int> Btr1,Btr2,Ltree,Rtree;
//pressfile.Read(&n,sizeof(BYTE));
UINT ReadByteCount=OFFSET;
if(pressfile.Open(filename1,CFile::modeRead,NULL))
{
pressfile.SeekToBegin();
pressfile.Read(&n,sizeof(BYTE));
pressfile.Read(&m,sizeof(BYTE));
}
for(int i=0;i<=m;i++)
{
pressfile.Read(&t[i],sizeof(BYTE));
pressfile.Read(&frequency[t[i]],sizeof(UINT));
}
Huffman huffman;
Btr1=Btr2=HuffmanTree(m);//重构霍夫曼树
presstofile.Open((LPCTSTR)filename2, CFile::modeWrite,NULL);
DWORD dwordflg=0;
while(ReadByteCount==OFFSET)
{
ReadByteCount=pressfile.Read(rd,OFFSET);
if(ReadByteCount==OFFSET)
{
for(UINT i=0;i<ReadByteCount/4;i++)
{
for(int k=31;k>=0;k--)
{
dwordflg=rd[i];//读出来的数据用DWORD类型的数组存
dwordflg= dwordflg>>31;
rd[i]= rd[i]<<1;
Btr1.BreakTree(Ltree,Rtree);
if(dwordflg)
Btr1=Rtree;
else Btr1=Ltree;
// Btr1=dwordflg?Rtree:Ltree;
if(!Btr1.huffmanTreeLeaves())//判断节点是否是叶子节点
{
write[Flag]=Btr1.Data();
Flag++;
Btr1=Btr2;
if(Flag==256)
{
presstofile.Write(&write,sizeof(write));
Btr1=Btr2;
Flag=0;
}
}
}
}
}
else
{
for(UINT i=0;i<ReadByteCount/4;i++)
{
for(int k=31;k>=0;k--)
{
dwordflg=rd[i];
dwordflg=dwordflg>>31;
rd[i]=rd[i]<<1;//左移一位,改变rd[]里的值,直到零
Btr1.BreakTree(Ltree,Rtree);
/*if(dwordflg)
Btr1=Rtree;
else Btr1=Ltree;*/
Btr1=dwordflg?Rtree:Ltree;//用原树的左右子树更新现在的树,dwordflg是零取左树,1取右树
if(!Btr1.huffmanTreeLeaves())//判断节点是否是叶子节点
{
if(i==(ReadByteCount/4-1)&&rd[i]==0)
{
presstofile.Write(&write,Flag);
return;
}
write[Flag]=Btr1.Data();
// Flag++;
Btr1=Btr2;
Flag++;
if(Flag==256)
{
presstofile.Write(&write,sizeof(write));
Btr1=Btr2;
Flag=0;
}
}
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -