当前位置:文档之家› LZW编码算法

LZW编码算法

班级 __ __ 学号__姓名 __ ___评分__________1.实验名称LZW编码与解码算法2.实验目的2.1通过实验进一步掌握LZW编码的原理;2.2 用C/C++等高级程序设计语言实现LZW编码。

3.实验内容步骤或记录(包括源程序或流程和说明等)3.1 实验原理(1)在压缩过程中动态形成一个字符列表(字典)。

(2)每当压缩扫描图像发现一个词典中没有的字符序列,就把该字符序列存到字典中,并用字典的地址(编码)作为这个字符序列的代码,替换原图像中的字符序列,下次再碰到相同的字符序列,就用字典的地址代替字符序列3.2实验步骤LZW编码算法的具体执行步骤如下:步骤1:开始时的词典包含所有可能的根(Root),而当前前缀P是空的;步骤2:当前字符(C) :=字符流中的下一个字符;步骤3:判断缀-符串P+C是否在词典中(1) 如果“是”:P := P+C // (用C扩展P) ;(2) 如果“否”①把代表当前前缀P的码字输出到码字流;②把缀-符串P+C添加到词典;③令P := C //(现在的P仅包含一个字符C);步骤4:判断码字流中是否还有码字要译(1) 如果“是”,就返回到步骤2;(2) 如果“否”①把代表当前前缀P的码字输出到码字流;②结束。

3.3 源程序#include<iostream>#include<string>using namespace std;const int N=200;class LZW{private: string Dic[200];//存放词典int code[N];//存放编码过的码字public: LZW(){//设置词典根Dic[0]='a';Dic[1]='b';Dic[2]='c';string *p=Dic;//定义指针指向词典中的字符} void Bianma(string cs[N]);//进行编码int IsDic(string e);//判断是否在词典中int codeDic(string f);void display(int g);//显示结果};void LZW::Bianma(string cs[N]){string P,C,K;P=cs[0];int l=0;for(int i=1;i<N;i++){C=cs[i];//当前字符(C) :=字符流中的下一个字符 K=P+C;if(IsDic(K)) P=K;//P+C在词典中,用C扩展P else{//P+C不在词典中code[l]=codeDic(P);Dic[3+l]=K;//将P+C加入词典P=C;l++;}if(N-1==i)//如果字符流中没有字符需要编码code[l]=codeDic(P);}display(l);}int LZW::IsDic(string e){//如果字符流中还有字符需要编码for(int b=0; b<200; b++){ if(e==Dic[b]) return 1; }return 0;}int LZW::codeDic(string f){int w=0;for(int y=0;y<200;y++)if(f==Dic[y]){w=y+1;break;}return w;}void LZW::display(int g){cout<<"经过LZW编码后的码字如下:"<<endl;for(int i=0;i<=g;i++)cout<<code[i];cout<<endl;cout<<"经LZW编码后的词典如下:"<<endl;for(int r=0;r<g+3;r++)cout<<r+1<<Dic[r]<<endl;}int main(){LZW t;string CSstream[N];// 存放要进行LZW编码的字符序列int length;// 要进行LZW编码的字符序列长度cout<<"请输入所求码子序列的长度:";cin>>length;while(length>=N){cout<<"该长度太长,请重新输入:";cin>>length;}cout<<"请输入要进行LZW编码的字符序列:"<<endl; for(int a=0;a<length;a++)cin>>CSstream[a];t.Bianma(CSstream);return 0;}4.实验环境(包括软、硬件平台)硬件:装有32M以上内存MPC;软件:Windows XP操作系统、Visual C++高级语言环境。

5.实验结果(截图)及分析6.实验存在问题和解决方法在设计过程中,设计LZW编码的算法比较复杂,不能很快地将编码思想转化为具体的编程语言,仔细地看过书上的相关介绍并通过上网参考才完成。

7.实验思考题7.1、分析LZW编码算法的优缺点。

LZW的优点是逻辑简单,实现速度快。

缺点是字典的生成和查找是基于顺序插入和检索模式,需要处理的数据量较大时会降低查找效率。

7.2、试编写LZW解码算法。

void update_wordlist(int*input){int i=0;int m;k=0;word*rear,*now,*current,*next;wordlist* wl_out,*wl_pre;wl_pre=NULL;//起始时先前前缀为空while(i<l){wl_out=wl_head;for(m=1;m<input[i];m++)wl_out=wl_out->next; //在词典中找待译码字对应的前缀if(wl_out!=NULL)//如果词典中有码字对应的前缀{now=wl_out->w_head;while(now!=NULL)//将此前缀存入到输出字符串中{output[k]=now->letter;now=now->next;k++;}if(wl_pre!=NULL)//先前前缀不空即不是译第一个码字时{current=new word;//将当前前缀的第一个字符取出current->letter=wl_out->w_head->letter;current->next=NULL;wl_rear=new wordlist;//在词典末尾存入新的前缀wl_now->next=wl_rear;wl_now=wl_rear;wl_rear->w_head=NULL;wl_rear->next=NULL;next=wl_rear->w_head;now=wl_pre->w_head;while(now!=NULL){if(next==NULL)//存入第一个字符与存入其他字符{//操作不同rear=new word;rear->letter=now->letter;rear->next=NULL;wl_rear->w_head=rear;next=wl_rear->w_head;}else{rear=new word;rear->letter=now->letter;rear->next=NULL;next->next=rear;next=rear;}now=now->next;}next->next=current;//将当前前缀的第一个字符加到新前缀}}else//词典中不含待译码字对应的前缀时{now=wl_pre->w_head;//将先前前缀的第一个字符取出current=new word;current->letter=now->letter;current->next=NULL;wl_rear=new wordlist;//在词典末尾存入新前缀wl_now->next=wl_rear;wl_now=wl_rear;wl_rear->next=NULL;wl_rear->w_head=NULL;next=wl_rear->w_head;while(now!=NULL){if(next==NULL)//存入第一个字符与存入其它字符{//操作不同rear=new word;rear->letter=now->letter;rear->next=NULL;wl_rear->w_head=rear;next=wl_rear->w_head;}else{rear=new word;rear->letter=now->letter;rear->next=NULL;next->next=rear;next=rear;}now=now->next;}next->next=current;//将先前前缀的第一个字符wl_out=wl_rear;//存入到新前缀末尾now=wl_rear->w_head;while(now!=NULL)//将新前缀存入到输出字符串{output[k]=now->letter;now=now->next;k++;}}wl_pre=wl_out;//当前前缀赋给先前前缀i++;}8.实验心得和建议通过这次实验,我们对LZW编码的思想和具体实现有了更深刻的了解。

我们不仅仅局限于简单的书面运算,编程上的实现对很多细节有着更多的要求。

这次实验锻炼了思考问题和解决问题的能力。

相关主题