设计hafuman 编码器与解码器 C++实现
2012-04-20 13:11
330 查看
这是本人在本科阶段的哈弗曼树的代码实现。设计hafuman 编码器与解码器
问题描述:利用哈夫曼编码进行信息通讯可以大大提高信道的利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传输数据预先编码;在接受端将传来的数据进行译码。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站编写一个哈夫曼码的编/译码系统。
基本要求:根据某字符文件统计字符出现频度,构造Huffman 树,编制Huffman编码,并将给定字符文件编码,生成编码文件;再将给定编码文件解码,生成字符文件。(要求按二进制位表示编码)英文文件。用二进制表示编码,生成二进制的编码文件。
欢迎 各位拍砖!
问题描述:利用哈夫曼编码进行信息通讯可以大大提高信道的利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传输数据预先编码;在接受端将传来的数据进行译码。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站编写一个哈夫曼码的编/译码系统。
基本要求:根据某字符文件统计字符出现频度,构造Huffman 树,编制Huffman编码,并将给定字符文件编码,生成编码文件;再将给定编码文件解码,生成字符文件。(要求按二进制位表示编码)英文文件。用二进制表示编码,生成二进制的编码文件。
#pragma once #ifndef HUFFMAN_H #define HUFFMAN_H #include <iostream> #include <string> using namespace std; //................ .h文件............ class node // 存放字符和字符频率类 { public: intsign; charch; intfrequence; node():frequence(0),sign(0){} node(charx,int f=0){ch=x;frequence=f;} node&operator =(const node& n){ch=n.ch;frequence=n.frequence;return *this;} }; //--------------------------------------------------以下是编码类------------------------------------- class hufftree; class huffnode {friend class hufftree; public: huffnode*next,*leftchild,*rightchild,*parent; intcode[100]; //.......存放编码....................// intdata; //..............权值.......................// charch; //字符// huffnode(huffnode*pnext=NULL,huffnode*left=NULL,huffnode*right=NULL) {next=pnext;leftchild=left;rightchild=right; }//..........数据成员初始花..........// huffnode(intitem,char a,huffnode *pnext=NULL,huffnode*left=NULL,huffnode*right=NULL) {data=item;ch=a;next=pnext;leftchild=left;rightchild=right;} }; class hufftree { public: nodearray[100]; //.........存放单一字符对象数组.......................// huffnode*head,*huffroot; hufftree(); voidInsert(int x,char a); //................插入...................// voidconnect(huffnode *p); //.....将接点链成单链表........// huffnode* Min();///......................求频率最小的那个接点 voidFrequence(char line[]);//// 求每个字符的频率 voidSethufftree();//..................造树problem....................... voidInorder(huffnode *r);//????????? voidoutput();//-------------------------------------输出函数--- voiddelet(huffnode * p); //...........................断开指针,没有删除---------- voidhuffcode(); // 构造huffman编码 voidoutputcode();//-----------------------------------------------输出编码----------- voidsortcode(); //............输出编码信息 voidIncode(char cha[]); //信息封装// voidtranscode(); // 进行译码 }; #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //#include "stdafx.h" #include "huffman.h" #include <iostream> #include <fstream> using namespace std; extern int number;//..........输入字符长度................// extern int a[100]; //....存放输入字符文件编码数组......// extern int maxsize;//........输入字符文件编码长度.............// int count; // 用来记录单一字符的长度 int len(char ch[])// 用来求字符串的长度 { inti(0),num(0); while(ch[i]!=NULL) { num++; i++; } number=num; returnnum; } hufftree::hufftree() // {huffnode *newnode=new huffnode(); head=newnode; head->next=NULL; } void hufftree::Insert(int x,chara)//===--------------------------插入函数------------------------- { huffnode*p,*pre; p=head->next; if(p==NULL) { huffnode*newnode=new huffnode(x,a,NULL,NULL,NULL); head->next=newnode; huffroot=newnode; } else {// huffnode(int item,char a,huffnode*pnext=NULL,huffnode*left=NULL,huffnode*right=NULL) //{data=item;ch=a;next=pnext;leftchild=left;rightchild=right;} huffnode*newnode=new huffnode(x,a,NULL,NULL,NULL); while(p) { pre=p; p=p->next; } pre->next=newnode; huffroot=newnode; } } void hufftree::connect(huffnode *p) // 将哈夫曼树树的叶子结点链成一个单链表(尾插法) { huffnode*t=head,*pre; while(t) { pre=t; t=t->next; } pre->next=p; p->next=NULL; } huffnode *hufftree:: Min()///-------------------------------求频率最小的那个接点 { if(head->next==NULL) {cout<<"文件为空!.."<<endl; returnNULL;} else { intmin=1000; huffnode*p=head->next; huffnode*t; while(p!=NULL) { if(min>p->data) { min=p->data; t=p; } p=p->next; } delet(t);//.......每次找到最小的接点后断开...........// returnt; } } void hufftree::Frequence(char line[])//// 求每个字符的频率 { char ch[100]; for(int x=0;x<len(ch);x++)//.....len(ch)=number..........// { ch[x]=line[x]; } int j(0),length(0); int i,k; int size=len(ch); for(k=0;k<size;k++) { if(ch[k]!=NULL) { array[j].ch=ch[k]; //.......存放单一字符并统计频率.................// for( i=0;i<size;i++) { if(ch[i]!=NULL) { if(array[j].ch==ch[i]) { ++array[j].frequence; ch[i]=NULL; } } } j++; } } length=j; count=length; //cout<<"length="<<length<<endl; /*for(i=0;i<length;i++) { cout<<"The"<<i<<"thchar is "<<array[i].ch<<" The frequence is"<<array[i].frequence<<endl; } */ } voidhufftree::Sethufftree()//-------------------------------建哈夫曼树-------------------------------------- { huffnode*pt=head->next; while(pt) { huffnode*p=Min(); huffnode*t=Min(); if(t==NULL)//最后一个接点// { Insert((p->data),NULL); } else { Insert((p->data+t->data),NULL); } huffroot->leftchild=p; huffroot->rightchild=t; p->parent=huffroot; if(t!=NULL) { t->parent=huffroot; } pt=head->next->next; if(pt==NULL) { huffroot->parent=pt; head->next=NULL; } } } //------------------------哈夫蔓树的中序遍历建立单连表------------------- void hufftree::Inorder(huffnode *r) { if(r!=NULL) { Inorder(r->leftchild); //cout<<r->data; if(r->leftchild==NULL&& r->rightchild==NULL) { connect(r); //cout<<r->ch; } Inorder(r->rightchild); } } //.....................-输出函数.................................// void hufftree::output() { huffnode*p=head->next;//头接点 while(p) { cout<<p->ch <<" " <<p->data <<endl; p=p->next; } } void hufftree::delet(huffnode * p)//----------------------断开指针------------- { huffnode*t=head->next,*pre=head; if(t==NULL){cout<<"All of the elements have been deleted!.."<<endl;exit(1);} else { while(t!=p) { pre=t; t=t->next; } pre->next=p->next; } } void hufftree::huffcode() // 构造huffman编码 { huffnode*p=head->next,*t; while(p!=NULL)//........遍历单连表(叶子结点).............// {int i=99; t=p;//??????? while(t->parent!=NULL)//..........将每个叶子结点的编码放到结点数组.....................// { if(t->parent->leftchild==t) { p->code[i]=0; i--; } else { p->code[i]=1; i--; } t=t->parent; } p=p->next; } } voidhufftree::outputcode()//----------------------输出编码每个字符的编码-------------------- { huffnode*p=head->next; intj(0); while(p) { //cout<<"\nThe char " <<p->ch <<" 's huffman codeis "; for(inti=0;i <100;i++) { if(p->code[i]==0|| p->code[i]==1) { //cout<<p->code[i]; a[j]=p->code[i];//.......将开始输入的字符编码放到一个数组..............// j++; } } p=p->next; } maxsize=j;//....a[i]字符编码的最大值.....// } void hufftree::sortcode() //............输出编码信息 { cout<<"编码后信息为:"<<endl; ofstreamoutfile2("file2.txt",ios::binary); if(!outfile2) {cout<<"open file2.txterror!"<<endl; exit(1); } for(int m=0;m<count;m++) { huffnode*p=head->next; //单链表// while(p) { if(array[m].ch==p->ch) { //cout<<"\nThechar "<<p->ch<<" 's huffman code is "; for(inti=0;i<100;i++) { if(p->code[i]==0|| p->code[i]==1) { outfile2.write((char*)&p->code[i],sizeof(p->code[i])); } } } p=p->next; } } outfile2.close(); ifstreaminfile2("file2.txt",ios::in|ios::binary); if(!infile2) {cout<<"open file2.txterror!"<<endl; exit(1); } infile2.read("file2.txt",100 ); while(p) {cout<<p->code[i]} infile2.close();*/ cout<<endl; } void hufftree::Incode(char cha[]) //信息封装// { intj=0; //cout<<"NUmber " <<len(cha) <<endl; /*for(intk=0;k <number;k++) //输出编码// { cout<<cha[k]; }*/ for(intm=0;m <number;m++) { huffnode*p=head->next; while(p) { if(cha[m]==p->ch) { //cout<<"\nThe char " <<p->ch <<" 's huffman codeis "; for(inti=0;i <100;i++) { if(p->code[i]==0|| p->code[i]==1) { //cout<<p->code[i]; a[j]=p->code[i];//........将开始输入的字符文件编码存入数组中.....................// j++; } } } p=p->next; } } maxsize=j; } void hufftree::transcode() // 进行译码 { ofstreamoutfile3("file3.txt"); if(!outfile3) {cout <<"open file3.txterror!" <<endl; exit(1);} huffnode *p=huffroot; //哈夫曼树// int i=0; cout <<"译码后信息为: "; while(p) { if(a[i]==0) p=p->leftchild; else p=p->rightchild; if(p->leftchild==NULL&& p->rightchild==NULL) { //cout<<p->ch; outfile3.put(p->ch); p=huffroot;//.........返回哈夫树根接点.............// } i++; if(i>=maxsize) break; } outfile3.close(); ifstreaminfile3("file3.txt",ios::in); char c; if(!infile3) cout <<"open error!"<<endl; while(infile3.get(c)) cout <<c; infile3.close(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //....................main()................. //#include "stdafx.h" #include <iostream> #include <fstream> #include <string> #include"huffman.h" using namespace std; int number=0; //存放字符串的长度 int a[100]; // 用来存放编码的数组 int maxsize=0; // 用来记录编码的长度 extern int count; // 用来记录字符的长度 hufftree list ; charch[100]; void qidong() { inti;ifstream infile("file1.txt",ios::in); if(!infile) {cout<<"open file1.txt error!" <<endl; exit(1); } for(i=0;i<100;i++) { infile>>ch[i]; if((ch[i]==' ')&&(ch[i+1]==' ')) break;} infile.close(); } void display() { for(int i=0;i <count;i++) { list.Insert(list.array[i].frequence,list.array[i].ch);//.......将字符链成链表.......// } } int main() { char op; intflag=1; while(flag) {cout<<endl <<"请选择:" <<endl; cout<<" 菜单 " <<endl; cout<<"1__启动要编码文件"<<endl; cout<<"2__编码 " <<endl; cout<<"3__输出解码后的文件"<<endl; cout<<"4__退出程序"<<endl; cout<<endl; cin>>op; switch(op) { case'1': cout<<"请启动要编码的文件:"<<endl; qidong();//...................调用字符文件..........// list.Frequence(ch);//.........求每个字符的频率 ........// display(); //list.output(); break; case'2': cout<<"对文件进行编码:"<<endl; list.Sethufftree();//............建哈夫曼树......................// list.Inorder(list.huffroot);//.........叶子结点链成单链表...............// //list.output(); list.huffcode();//.........构造huffman编码.......// list.sortcode(); //.............输出编码............// break; case'3': cout<<"编码后的文件为:"<<endl; list.Incode(ch);//编译字符文件对应码的信息// list.transcode();//.......输出译码信息...........// cout<<endl; break; case'4': flag=0; cout<< "程序结束,按任意键退出"<<endl; break; default: cout<<"输入错误,请重新输入!"<<endl; } } system("pause"); return0; }
欢迎 各位拍砖!
相关文章推荐
- PAT程序设计考题——甲级1005( Spell It Right ) C++实现
- 常见设计模式的解析和实现(C++)之九—Decorator模式
- 设计模式C++实现(14)——职责链模式
- 设计模式之抽象工程模式Abstract Factory Pattern()C++实现
- 设计模式之适配器模式(Adapter)C++实现
- 设计模式(二)之抽象工厂模式(Abstract Factory) C++实现
- 通过例子学设计模式之--简单工厂模式以及使用场景说明(C++实现)
- 常见设计模式的解析和实现(C++)之九-Decorator模式
- 设计模式---策略模式(C++实现)
- 设计模式C++实现(15)——观察者模式
- 设计模式--生成器实现C++
- 设计模式-组合模式 C++实现
- 设计模式:策略模式的实现 c++ 与 java
- 23种设计模式之单例模式(创建型,3 Singleton,c++实现)
- 设计模式C++实现:组合模式
- 设计模式C++实现(11)——装饰模式
- 设计模式C++实现——抽象工厂模式
- [GoF设计模式]Proxy模式和Strategy模式的C++实现
- 设计模式之适配器,C++实现
- C++:多线程类库的设计与实现(三)