C++ LZW算法

来源:互联网 发布:淘宝店铺推广策划书 编辑:程序博客网 时间:2024/05/29 16:57

LZW算法,用于高重复率的无损文本压缩,压缩率达30%~50%,然而经过实测发现,对于普通文章文本,就算经过优化,效果也只能说很一般吧。然而这个算法的实现也让我头疼了一阵子,这种推理算法确实恶心,非常抽象,本来写完KMP之后就打算把这算法写一遍,然而为了优化,又卡住了一会,在今晚终于大功告成。


压缩部分应该很容易看明白,就是解压的时候,需要考虑如果字典里没有,则一定是连续重复的字符,就是取entry首字符不是特别容易看明白,其他看着源代码和我下面从别处找的一张图多顺着推几遍应该就能明白。若要将压缩后文本保存到文件,序列化list即可



#include<iostream>#include<map>#include<string>#include<list>#include<sstream>#include<fstream> using namespace std;void PushToResult(int count,list<string>& compressed_content,string& temp_str,map<string,int>& _map){char s[12];itoa(count,s,10);//comput now index will occupy how much spaceif(strlen(temp_str.c_str())<strlen(s)){//if compress occupy more space,choose original elem to savecompressed_content.push_back(temp_str);}else{char s[12];itoa(_map[temp_str],s,10);compressed_content.push_back(s);}}void Compress(string source,list<string>& compressed_content){map<string,int> _map;int count=0;for(;count<256;count++){_map[string(1,count)]=count;}string temp_str="";temp_str+=source[0];//put first into temp_strchar temp_char;for(int i=1;i<source.length();i++){temp_char=source[i];//temp_char start from second charstring entry=temp_str+temp_char;if(_map.count(entry)){//look up wheather it is in _maptemp_str+=temp_char;//if it is in _map,add next into temp_str}else{PushToResult(count,compressed_content,temp_str,_map);//push result except temp_char_map[entry]=count++;//push temp_str+temp_char into _maptemp_str=temp_char;}}PushToResult(count,compressed_content,temp_str,_map);}string Decompress(list<string>& compressed_content){map<int,string> _map;int count=0;for(;count<256;count++){_map[count]=string(1,count);}stringstream ss;string temp_str="";string temp_entry="";//the same as compress to make _map,put first into temp_strint temp=atoi((compressed_content.front()).c_str());if(temp<256){ss<<compressed_content.front();temp_str+=compressed_content.front();}else{if(_map.count(temp)){ss<<_map[temp];temp_str+=_map[temp];}}compressed_content.pop_front();for(list<string>::iterator iter=compressed_content.begin();iter!=compressed_content.end();++iter){int temp=atoi((*iter).c_str());if(temp<256){//if not compressedss<<*iter;temp_entry=(*iter);}else{if(_map.count(temp)){//if it is in _mapss<<_map[temp];temp_entry=_map[temp];}else{//it must be same char ,like aaaaa..temp_entry+=temp_entry[0];ss<<temp_entry;}}temp_str+=temp_entry[0];_map[count++]=temp_str;temp_str=temp_entry;}return ss.str();}int main(){list<string> compressed_content;ifstream in("content.txt");string source((istreambuf_iterator<char>(in)),istreambuf_iterator<char>());in.close();Compress(source,compressed_content); string content="";for(list<string>::iterator iter=compressed_content.begin();iter!=compressed_content.end();++iter){content+=*iter;}cout<<"original:"<<endl<<source<<endl<<endl;//original text cout<<"compressed:"<<endl<<content<<endl<<endl;//compressed text cout<<"decompressed:"<<endl<<Decompress(compressed_content)<<endl<<endl;cout<<endl;cout<<"original size:"<<source.size()<<endl;cout<<"compressed size:"<<content.size()<<endl;return 0;} 


图片来自:http://blog.csdn.net/abcjennifer/article/details/7995426



0 0
原创粉丝点击