⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decode.cpp

📁 huffman decode all you need is input a data so that it will decode
💻 CPP
字号:
#include<iostream>
#include<fstream>
#include<cmath>
#define debug if(0)
#include "MinHeapTree.h"
using namespace std;
class node{
	public:
	int v;
	node *r,*l;
	char *code;
	int asc;
	node(int i,int ch){
		v=i;
		r=0;
		l=0;
		asc=ch;
		code=0;
	}
	~node(){
		delete r;
		delete l;
		delete code;
	}
	void setcode(char *co,char *ac){
		if(code)delete code;
		code=new char[strlen(co)+2];
		strcpy(code,co);
		strcat(code,ac);
		if(l)l->setcode(code,"0");
		if(r)r->setcode(code,"1");
	}
	void add(node * newer1,node * newer2){
		v = newer1->v ;
		l=newer1;
		if(newer2){
			v += newer2->v ;
			r=newer2;
		}
	}
};
int compare(node *a,node *b){
	return a->v-b->v;
}

class Huffman_code{
	public:
		unsigned char c;
		int n;
		char**code;
		Huffman_code(){
			code=0;
			n=0;
		}
		void print(ostream *fout,int i){
			if(n){
				if(i!=256){
					(*fout)<<(int)(unsigned char)c;
					if(c=='\n')(*fout)<<"\t\'\\n\'";  
					else if(c=='\r')(*fout)<<"\t\'\\r\'";  
					else if(c=='\t')(*fout)<<"\t\'\\t\'";  
					else (*fout)<<"\t\'"<<c<<"\'";  
				}else (*fout)<<"EOF\teof";
				(*fout)<<"\t"<<n<<"\t";
				if(code)if(*code)(*fout)<<(*code);
				(*fout)<<endl;
			}
		}
};
class readbit{
	istream *fin;
	unsigned char binary;
	char temp;
	public:
		readbit(istream *instream){
			fin=instream;
			binary=0;
		}
		bool read(bool *bit){
			if(binary){
				if(temp & binary)*bit=true;
				else *bit=false;
				binary>>=1;
				return true;
			}else{
				if(fin->read(&temp,1)){
					binary=128;
					return read(bit);
				}else return false;
			}
		}
};
class writebit{
	ofstream *fout;
	char temp;
	int i;
	public:
		int allsize;
	writebit(ofstream *fileopen){
		fout=fileopen;
		i=7;
		temp=0;
		allsize=0;
	}
	void write(char code){
		for(unsigned char j=128;j!=0;j>>=1){
			if(code & j)write("1");
			else write("0");
		}
	}
	void write(char *code){
		if(*code){
			allsize++;
			if(*code=='1')temp+=(char)pow((double)2,i);
			i--;
			if(i<0){
				i+=8;
				fout->write(&temp,1);
				temp=0;
			}
			write(++code);
		}
		
	}
	void close(){
		if(i!=7)fout->write(&temp,1);
		fout->close();
	}
};
class Huffmantable{
	Huffman_code hc[257];
	node *root;
	public:
		Huffmantable(){
			root=0;
			for(int i=0;i<256;i++){
				hc[i].c=(char)i;
			}
			hc[256].c=1;
			hc[256].n=1;
		}
		void add(unsigned char c){
			hc[(int)c].n++;
			
		}
		node* readhct(readbit *rb){
			bool bit=1;
			node *newnode;
			if(root){
				rb->read(&bit);
			}
			if(bit){
				newnode=new node(-1,-2);
				if(!root)root=newnode;
				newnode->l=readhct(rb);
				newnode->r=readhct(rb);
				return newnode;
			}else{
				unsigned char temp=0;
				rb->read(&bit);
				if(bit){
					temp=0;
					for(unsigned char i=128;i>0;i>>=1){
						rb->read(&bit);
						if(bit)temp|=i;
					}
					newnode=new node(-1,(unsigned char)temp);
					hc[temp].n=1;
					hc[temp].code=&newnode->code;
					return newnode;
				}else {
					newnode=new node(1,-1);
					hc[256].code=&newnode->code;
					return newnode;
				}
			}
		}
		void writehct(node *n,writebit *wf){
			if(n!=root){
				if(n->asc > -2){
					wf->write("0");
					if(n->asc == -1)wf->write("0");
					else {
						wf->write("1");
						wf->write((char)n->asc);
					}
				}else wf->write("1");
			}
			if(n->l)writehct(n->l,wf);
			if(n->r)writehct(n->r,wf);
		}
		
		
		void buildtree(){
			minheaptree <node*> *mht=new minheaptree <node*>(compare);
			node* tn1;
			node* tn2;
			if(root)delete root;
			root=0;
			for(int i=0;i<257;i++){
				if(hc[i].n){
					if(i==256)tn1=new node(1,-1);
					else tn1=new node(hc[i].n,hc[i].c);
					hc[i].code=&tn1->code;
					mht->add(tn1);
				}
			
			}
			cout<<endl;
			while(!mht->isempty()){
				tn2=0;
				if(root)mht->add(root);
				tn1= mht->minimum();
				if(!mht->isempty()){
					tn2= mht->minimum();
				}
				root=new node(-1,-2);
				root->add(tn1,tn2);
			}
			root->setcode("","");
			delete mht;
		}
		void print(ostream *fout=&cout){
			(*fout)<<"Huffman encoding table:\n";
			(*fout)<<"Decimal-character-frequency-Huffman_code\n";
			for(int i=0;i<257;i++)
				hc[i].print(fout,i);
		}
		void zipfile(char *readfile,char *writefile){
			ifstream fin(readfile,ios::binary);
			ofstream fout(writefile,ios::binary);
			writebit wf(&fout);
			writehct(root,&wf);
			unsigned char temp;
			int bs=0,as=0;
			while(fin.read((char *)&temp,1)){
				bs+=8;
				wf.write( *(hc[(int)temp].code) );
				as+=strlen(*(hc[(int)temp].code));
				
			}
			as+=strlen(*(hc[256].code));
			wf.write( *(hc[256].code) );
			wf.close();
			printf("Huffman to ASCII encoding ratio = %d/%d = %.2f%%\n",as,bs,100.0*as/bs);
			printf("Huffman(include tree) to ASCII encoding ratio = %d/%d = %.2f%%\n",wf.allsize,bs,100.0*wf.allsize/bs);
		}
		void unzipfile(char *readfile,char *writefile){
			ifstream fin(readfile,ios::binary);
			ofstream fout(writefile,ios::binary);
			node * pointer=0;
			bool bit;
			readbit rb(&fin);
			
			if(root)delete root;
			root=0;
			root=readhct(&rb);
			root->setcode("","");
			pointer=root;
			while(rb.read(&bit)){
				
				if(bit) pointer=pointer->r;
				else pointer=pointer->l;
				if(pointer->asc > -2){
					if(pointer->asc >= 0){
						fout<<(char)pointer->asc;
						pointer=root;
					} else{
						fin.close();
						fout.close();
						return;
					}
				}
				
			}
			
		}
};

int main(int argc,char*argv[]){
	Huffmantable ht;
	if(argc<2)return 0;
	cout<<"unziping..."<<endl;
	if( argc==2 )ht.unzipfile(argv[1],"9517144.txt");
	else ht.unzipfile(argv[1],argv[2]);
	ofstream fout("codebook.txt");
	ht.print(&fout);
	ht.print();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -