LZW 压缩算法的C++实现
来源:互联网 发布:js的闭包是什么 编辑:程序博客网 时间:2024/05/24 04:34
最近老师布置了一个上机作业,实现LZW 。刚好最近对STL掌握的还不错,写起来就比较容易,又一次体会到了C++模版库的强大,要不然代码量就*2了。
不知道老师的要求是对ASCCI码所有的字符进行压缩编码还是只对输入字符串的进行编码,不过算法都一样,我是对根据输入的串进行构造字典表,如果直接对256个字符进行构造,那更简单了。
结下来就先说一说LZW的算法,它属于无损压缩的一种,尤其对输入重复的串压缩的越彻底。
基础思想:
利用字符的重用性,每当输出一个编码,就讲一个新的string 存放到字典表中
算法流程:
1.初始化,将所有的单字符放入字典表中(这里的字符是指输入字符串中不重复的字符)
2.读入一个输入给前缀串,赋值给W
3.读入一个输入字符,赋值给K
判断:
if 没有这样的K(指输入的字符串结束了),就输出最后一个W代表的码字,break;
if WK(指将WK两个字符串合并成一个)存在于字典表
{W=WK;repeat3;}
if WK不再字典表
{输出W代表的码字,WK加进字典表;W=K;repeat3;}
具体可以看看下面的示例:
输入串ABABB
构造初始字典表并同时进行编号(即流程中所说的码字):
A1B2
接下来第一个流程 :
W=A
K=B
判断WK=AB不在字典表中,输出W代表的码字A--1,WK=AB加入字典表,W=K=B,repeat3
A1B2AB3
第二个流程:
W=B
K=A
判断WK=BA不在字典表中,输出W代表的码字B--2,WK=BA加入字典表,W=K=A,repeat3
A1B2AB3BA4
第三个流程:
W=A
K=B
判断WK=AB在字典表中,W=WK=AB,repeat3
第四个流程:
W=AB
K=B
判断WK=ABB不再字典表中,输出W代表的码字AB--3,WK=ABB加入字典表,W=K=B,repeat3
A1B2AB3BA4ABB5第五个流程:
W=B
K='\0' 输入穷尽,输出W代表的码字B--2
综上最后的压缩后的编码为 1232.
我这个可能是按照流程走的一遍比较麻烦,不过如果大家有耐心的话走一遍就全部明白了
解码就是压缩的逆过程,根据输入的编码流从字典表中找字符,简单。
实现代码如下:
#include <iostream>#include <cstdio>#include <cstring>#include <map>#include <algorithm>#include <vector>using namespace std;long len=0;//原字符串的长度long loc=0;//去重之后字符串的长度map<string,long> dictionary;vector <long> result;#define MAX 100;void LZWcode(string a,string s){ //memset(&result,0,sizeof(int)); string W,K; for(long i=0;i<loc;i++) { string s1; s1=s[i];//将单个字符转换为字符串 dictionary[s1]=i+1; } W=a[0]; loc+=1; for(int i=0;i<len-1;i++) { K=a[i+1]; string firstT=W; string secontT=W; if(dictionary.count(firstT.append(K))!=0)//map的函数count(n),返回的是map容器中出现n的次数 W=firstT; else { result.push_back(dictionary[W]); dictionary[secontT.append(K)]=loc++; W=K; } } if(!W.empty()) result.push_back(dictionary[W]); for(int i=0;i<result.size();i++) cout<<result[i];}void LZWdecode(int *s,int n){ string nS; for(int i=0;i<n;i++) for(map<string,long>::iterator it=dictionary.begin(); it!=dictionary.end();it++) if(it->second==s[i]) { cout<<it->first<<" "; } for(map<string,long>::iterator it=dictionary.begin(); it!=dictionary.end();it++)//输出压缩编码的字典表 cout<<it->first<<" "<<it->second<<endl;}int main(int argc, char const *argv[]){ cout<<"本程序的解码是根据输入的编码字符进行的解码,并不是全256 的字符"<<endl; cout<<"选择序号:"<<endl; cout<<"1.压缩编码 2.解码"<<endl; int n; while(scanf("%d",&n)!=EOF) { switch(n) { case 1: { char s[100],a[100]; cout<<"输入一串字符:"<<endl; cin>>s; len=strlen(s); for(int i=0;i<len;i++) a[i]=s[i]; sort(s,s+len);//排序 loc=unique(s,s+len)-s;//去重 LZWcode(a,s); break; } case 2: { cout<<"输入解码数组的长度:"<<endl; int changdu; cin>>changdu; cout<<"输入解码数串(每个数串以空格隔开):"<<endl; int s[changdu]; for(int i=0;i<changdu;i++) cin>>s[i]; LZWdecode(s, changdu); break; } default: cout<<"你的输入不正确,请从重新开始"<<endl; } if(n==2) { auto iter=result.begin(); // 每次正确输入结束后对结果进行清零 while(iter!=result.end()) result.erase(iter++); } } return 0;}
- lzw压缩算法的c语言实现
- lzw压缩算法的c语言实现
- LZW算法压缩c语言实现
- LZW算法压缩c语言实现
- java实现的LZW 压缩算法源码
- LZW 压缩算法的C++实现
- lzw字符串压缩算法实现
- LZW压缩的js实现
- LZW算法的 C#实现
- 关于LZW算法的压缩与解压缩
- LZW压缩算法
- lzw压缩算法
- lzw 压缩算法源代码
- LZW压缩算法源代码
- lzw图像压缩算法
- LZW 压缩算法
- 压缩算法-LZW
- LZW压缩算法
- 排序算法之选择排序
- Leetcode学习(32)—— Maximum Depth of Binary Tree
- scala习题精选100道
- 剖析智能指针
- Ubuntu下安装git及配置使用github
- LZW 压缩算法的C++实现
- 利用Future异步获取多线程的返回结果
- 高德地图之实时导航
- eclispse常用快捷键
- Intellij idea 的maven项目如何通过maven自动下载jar包
- 一个Jsp写的木马文件
- IOS个人账户转公司账户,TPshop APP提交审核
- SAS:proc sql中对空值(缺失值)的处理
- css---border属性实现小三角型