LZW压缩算法
来源:互联网 发布:淘宝信用贷款逾期 编辑:程序博客网 时间:2024/05/22 11:56
1.LZW压缩适用的场景:
对于有大量重复出现的字符或者字符串,可以将重复出现的多个串用一个字符表示,并写进文件。比如可以压缩这个字符串:“TOBEORNOTTOBEORTOBEORNOT”,这个字符串中出现了大量的TO,BE,OR,NOT等等字符,我们就可以将这些重复出现的字符压缩写进文件。这里只是说明算法,并没有涉及写进文件的操作。
2.压缩和解压缩的原理:
(1)压缩:这里定义一个字典,字典里存放字符或者字符串的编码。一开始字典被初始化为:
A:1 B:2 C:3 D:4 ..... Y:25 Z:26
之后,出现字母T,我们就将20(ASCII中20对应的字符)写进压缩文件,然后将TO写进字典并编号27.下一个读到字符O,将15写进压缩文件,OB写进字典等等。所以,字典就会被扩充。
TO:27
OB:28
BE:29
EO:30
等等。
所以,压缩的时候,只需要将出现的字符或者字符串(有在字典中出现过)的编码写进压缩文件即可,(比如,TO在字典中出现过,我们就将TO的编码写进文件,不会单独记录T和O),并将当前的字符或者字符串与下一个字符组成新的串写进字典。
(2)解压缩:用编码找到对应的字符或者字符串,然后写进解压缩文件(比如,看到编码15,就会将T写入解压缩文件)。
3.代码实现:
#include<iostream>using namespace std;#include<string>//LZW压缩和解压缩typedef struct Dict{ string _s; int _code;}Dict;class Compress{public: Compress(int maxSize,string text) { _maxSize = maxSize; _code = new int[maxSize]; _size = 0; _text = text; _dict = new Dict[_maxSize]; _dictSize = 0; //过滤0号位置 Insert("#"); //向字典中插入26个字母 string s = "A"; for (int i = 0; i < 26; ++i) { Insert(s); s[0]++; } } ~Compress() { delete[] _code; delete[] _dict; _code = NULL; _dict = NULL; _maxSize = 0; _size = 0; } string Encode() { string s;//存储压缩后的字符串 string cur; char next; int i = 0; while (i < _text.size()) { cur.insert(cur.size(),1, _text[i]); i++; next = _text[i]; while (FindCode(cur) != -1)//当前串在字典中 { cur.insert(cur.size(), 1, next); ++i; if (i != _text.size()) next = _text[i]; else break; } if (i != _text.size()) { char c = cur.at(cur.size() - 1); cur.erase(cur.end()-1); _code[_size] = FindCode(cur); ++_size; cur += c; c = _code[_size-1]; s.push_back(c); Insert(cur); } if(i == _text.size() && FindCode(cur) != -1) { _code[_size] = FindCode(cur); s.push_back(_code[_size]); break; } --i; cur.clear(); } return s; } string Decode(const string& s) { string text; string cur; if (s.size() <= 0) return s; int code; for (int i = 0; i < s.size(); ++i) { code = (int)(s[i]); cur = FindSeq(code); text += cur; } return text; } void PrintDict() { cout<<"seq code"<<endl; for (int i = 0; i < _dictSize; ++i) { cout << _dict[i]._s << " " << _dict[i]._code<<endl; } }protected: int FindCode(const string& s) { for (int i = 0; i < _dictSize; ++i) { if (s == _dict[i]._s) return i; } return -1; } string FindSeq(int code) { return _dict[code]._s; } void Insert(string seq) { _dict[_dictSize]._s = seq; _dict[_dictSize]._code = _dictSize; _dictSize++; }private: Dict* _dict; int _dictSize; int* _code; int _size; int _maxSize; string _text;};int main(){ string text; cin >> text; Compress c(100,text); //c.PrintDict(); string s = c.Encode(); // c.PrintDict(); //cout << s; cout<<c.Decode(s)<<endl; system("pause"); return 0;}
代码运行结果:
当然了,要实现真正的压缩,就要把压缩信息写进文件。如果要将压缩和解压缩进行分离的话,还需要在解压缩的时候,完成一次字典的填充工作。
这里只是为了说明算法而已。
0 0
- LZW压缩算法
- lzw压缩算法
- lzw 压缩算法源代码
- LZW压缩算法源代码
- lzw图像压缩算法
- LZW 压缩算法
- 压缩算法-LZW
- LZW压缩算法
- LZW压缩算法
- LZW压缩算法
- LZW压缩算法
- LZW压缩算法
- LZW压缩算法
- LZW算法压缩和解压缩
- LZW压缩算法js版
- 关于LZW压缩算法[转]
- LZW压缩算法js版
- lzw字符串压缩算法实现
- codevs 1002 搭桥
- 颜色矩阵滤镜理解
- 线性表c语言实现----初始化插入删除
- 升级Xcode8后的相机crash问题-IOS10权限问题
- 最新Arcgis API for JS 展示WebGIS实际生产生活应用案例
- LZW压缩算法
- 设计模式学习--策略模式
- 【LeetCode】53. Maximum Subarray
- 关于PHP NGINX PHP 如何配合工作
- 共享单车丢失里的产品设计。 你会怎样解决?
- SparkSQL中DataFrame Operations操作(select、filter、groupBy、count)
- 腾云阁「腾讯云的1001种玩法」征文活动
- appium+Python :操作键盘搜索响应事件
- HihoCoder 状态压缩二