头文件"Compressor.h"
#include<iostream>
#include"HuffmanTree.h"
#include<string>
#include<fstream>
#include<map>
using namespace std;
class Compressor{
public:
HuffmanTree * tree;
string *str;//存放每个字符对应的huffman码
int cnt[128];//每个字符出现的次数
Compressor(){
for(int i=0;i<128;i++)
cnt[i]=0;
tree= new HuffmanTree;//
}
~Compressor(){
delete tree;
}
void Compress(){
char ch;//记录出现的字符
int value=0;
ifstream in("C:\\Article.txt",ios::in);
ofstream out("C:\\code.txt",ios::out|ios::trunc);
if(!in||!out){
cout<<"error"<<endl;
return ;
}
while((ch=in.get())!=EOF){
value=ch;
out<<str[value];
}
in.close();
out.close();
}
void Decompress(){
char ch;
map<string,char> m;
ifstream in("C:\\code.txt",ios::in);
ofstream out("C:\\output.txt",ios::out|ios::trunc);
if(!in||!out){
cout<<"error"<<endl;
return ;
}
for(int i=0;i<128;i++){
if(str[i][0]!='\0'){
m[str[i]]=i;
}
}
string tmp;
while((ch=in.get())!=EOF){
tmp+=ch;
if(m.find(tmp)!=m.end()){
out<<m[tmp];
tmp="";
}
}
in.close();
out.close();
}
void BuildHuffmanTree(){
char ch;//记录出现的字符
int value;
ifstream in("C:\\Article.txt",ios::in);
if(!in){
cout<<"error"<<endl;
return ;
}
while((ch=in.get())!=EOF){
value=ch;
cnt[value]++;
}
tree->BuildTree(cnt,128);
tree->HuffmanCoding();
str=tree->CodeTable();
in.close();
}
};
头文件"HuffmanTree.h"
#include<iostream>
#include<queue>
#include<stack>
#include<string>
using namespace std;
class HuffmanTreeNode{
public:
unsigned char colorNum;//颜色的灰度值
int colorCnt;//灰度值出现的次数(权值)
string code;//颜色对应huffman编码
HuffmanTreeNode *left;
HuffmanTreeNode *right;
HuffmanTreeNode *parent;
HuffmanTreeNode(){
colorCnt=0;
parent=NULL;
left=NULL;
right=NULL;
}
};
struct ltstr
{
bool operator()( HuffmanTreeNode* h1, HuffmanTreeNode* h2)
{
return h1->colorCnt<h2->colorCnt;
}
};
class HuffmanTree{
public:
HuffmanTreeNode *root;
HuffmanTree(){
root=NULL;
}
virtual ~HuffmanTree(){
//DeleteTree(root);
}
void BuildTree(int cnt[],int n){
priority_queue<HuffmanTreeNode *,vector<HuffmanTreeNode *>,ltstr> minQueue;
HuffmanTreeNode *first, *second;
HuffmanTreeNode *current;
int count=0;//记录一共有多少种颜色出现
for(int i=0;i<n;i++){
//构造n个权值为cnt[i]的只有根节点的二叉树
if(cnt[i]!=0){
current=new HuffmanTreeNode;
current->colorCnt=cnt[i];
current->colorNum=i;
minQueue.push(current);
count++;
}
}
for(int i=0;i<count-1;i++){
first=minQueue.top();
minQueue.pop();
second=minQueue.top();
minQueue.pop();
root=MergeTree(first,second);
minQueue.push(root);
}
}
void DeleteTree(HuffmanTreeNode *&cur){
if(cur){
DeleteTree(cur->left);
DeleteTree(cur->right);
delete cur;
cur=NULL;
}
}
HuffmanTreeNode *MergeTree(HuffmanTreeNode *h1,HuffmanTreeNode *h2){
HuffmanTreeNode *top=new HuffmanTreeNode;
top->left=h1;
top->right=h2;
top->left->parent=top;//父子结点连接
top->right->parent=top;
top->colorCnt=h1->colorCnt+h2->colorCnt;
return top;
}
void HuffmanCoding(){
HuffmanTreeNode *p=root;
queue<HuffmanTreeNode *> nodeQueue;
stack<char> st;
if(p)
nodeQueue.push(p);
while(!nodeQueue.empty()){
p=nodeQueue.front();
nodeQueue.pop();
//当结点为叶子结点
if(!p->left&&!p->right){
HuffmanTreeNode *tmp=p;
while(tmp->parent){
if(tmp->parent->left==tmp){
tmp=tmp->parent;
st.push(48);
}
else if(tmp->parent->right==tmp){
tmp=tmp->parent;
st.push(49);
}
}
while(!st.empty()){
p->code+=st.top();
st.pop();
}
}
if(p->left){
nodeQueue.push(p->left);
}
if(p->right){
nodeQueue.push(p->right);
}
}
}
string *CodeTable(){
queue<HuffmanTreeNode *> nodeQueue;
string *str=new string[128];
HuffmanTreeNode *p=root;
if(p)
nodeQueue.push(p);
while(!nodeQueue.empty()){
p=nodeQueue.front();
nodeQueue.pop();
//当结点为叶子结点
if(!p->left&&!p->right){
str[p->colorNum]=p->code;
}
else{
if(p->left)
nodeQueue.push(p->left);
if(p->right)
nodeQueue.push(p->right);
}
}
return str;
}
};
源文件"main.cpp"
#include <iostream>
#include<string>
#include"Compressor.h"
using namespace std;
int main(){
Compressor cpr;
cpr.BuildHuffmanTree();
cpr.Compress();
cpr.Decompress();
return 0;
}