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

原创 2013年12月04日 09:35:24

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










相关文章推荐

霍夫曼编码应用

假设一串由大写字母构成的电文,采用霍夫曼规则对其进行编码,以菜单方式设计并完成功能任务:建立霍夫曼树、霍夫曼编码生成、编码文件译码。 思路:(该题考察的是霍夫曼树,霍夫曼编码等知识) 创建霍夫曼树可以...

C++ STL 优先队列 及其 霍夫曼编码应用示例

优先队列(priority queue) 优先队列是一种比较常用的结构,普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。 当访问元素时,具有最高优...

香农,霍夫曼编码

  • 2015年12月14日 20:35
  • 36KB
  • 下载

霍夫曼编码

  • 2015年07月14日 21:46
  • 3KB
  • 下载

JPEG 编解码器 霍夫曼编码

arm11中的JPEG 编解码器 霍夫曼编码是一种被广泛应用而且非常有效的数据压缩技术,根据待压缩数据的特征,一个可压缩掉20%~90%。这里考虑的数据指的是字符串序列。要理解霍...

霍夫曼编码解码

  • 2013年05月12日 14:20
  • 6KB
  • 下载

霍夫曼编码及译码

  • 2014年05月17日 12:22
  • 5KB
  • 下载

算法设计与分析--霍夫曼树编码(C++实现)

问题描述: 设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为{w1, w2, …, wn},应用哈夫曼树构造最短的不等长编码方案。 Huffman算法: ...
  • wwj_748
  • wwj_748
  • 2013年05月27日 19:29
  • 8368

霍夫曼编码对图像压缩解压

  • 2017年07月22日 09:13
  • 11.55MB
  • 下载

霍夫曼(huffman)编码C++程序

  • 2010年04月21日 17:22
  • 190KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:霍夫曼编码应用--文本转换
举报原因:
原因补充:

(最多只允许输入30个字)