设计hafuman 编码器与解码器 C++实现
来源:互联网 发布:粤语听书软件 编辑:程序博客网 时间:2024/06/05 17:38
这是本人在本科阶段的哈弗曼树的代码实现。设计hafuman 编码器与解码器
问题描述:利用哈夫曼编码进行信息通讯可以大大提高信道的利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传输数据预先编码;在接受端将传来的数据进行译码。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站编写一个哈夫曼码的编/译码系统。
基本要求:根据某字符文件统计字符出现频度,构造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;}
欢迎 各位拍砖!
- 设计hafuman 编码器与解码器 C++实现
- Java EE HTML5 WebSocket 编码器与解码器的例子
- Java EE HTML5 WebSocket 编码器与解码器的例子
- JPEG编码器和解码器
- 基于TMS320DM642的MPEG4编码器的设计与实现
- 接上一篇改篇:Java EE7,Tomcat8,HTML5,WebSocket1编码器与解码器的例子
- 疯狂Spring Cloud连载(11)Feign的编码器与解码器
- 【Stones from other hills】基于TMS320DM642的MPEG4编码器的设计与实现
- 【Stones from other hills】基于TMS320C64x DSPs的MPEG-4实时编码器设计与实现
- 【Stones from other hills】基于TMS320C64x DSPs的MPEG-4实时编码器设计与实现
- 编码器设计
- 二进制算术编码器的C语言实现
- 项目01-CDMA信道编码器/解码器
- Speex之四--编码器/解码器命令行
- ffmpeg中G726解码器用法 编码器用法
- 矩阵 分配器 切换器 编码器 解码器 中控器
- netty:protobuf的编码器ProtobufVarint32LengthFieldPrepender()、解码器ProtobufVarint32FrameDecoder()
- ffmpeg中G726解码器用法 编码器用法
- SVN常用命令
- chattr与lsattr
- 二叉查找树练习
- 计算机网络 数据传输方式
- 时钟和抽奖
- 设计hafuman 编码器与解码器 C++实现
- 让Firefox的密码框永远都可以自动完成(For Firefox 4&5)
- linux下查看系统资源和负载,以及性能监控
- MYSQL常用命令总结
- B树的原理与实现(C++)
- 彩信的读取
- 解决方案:某些网页Firefox不能记住密码
- PowerPC家族谱系详解
- 主元素!!zoj 2132