霍夫曼编码应用--文本转换

头文件"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;
}










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值