关闭

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

标签: 数据结构c++Huffman
304人阅读 评论(0) 收藏 举报
分类:

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










0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3249次
    • 积分:113
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档