#include<string>
#include<vector>
#include<iostream>
#include<queue>
#include<unordered_set>
#include<algorithm>
#include<cassert>
#include<list>
#include<map>
#include<fstream>
using namespace std;
template <class CODE>
class Lzw
{
public:
static bool Encode(const string &,const string &);
static bool Decode(const string &,const string &);
//不管是时间还是空间,都输给了ZIP...
};
template <class CODE>
bool Lzw<CODE>::Encode(const string &src,const string &dest)
{
//dict 初始化,prefix 初始化
map<string,CODE> dict;
CODE num=0;
for(num=0;num<128;num++)
{
string newItem(1,char(num));
dict[newItem]=num;
}
string prefix("");
FILE * fSrc=fopen(src.c_str(),"r");
FILE * fDest=fopen(dest.c_str(),"wb+");
//算法主体
char cur;//当前字符
while(fread(&cur,sizeof(char),1,fSrc) && !feof(fSrc))
{
string tmp(1,cur);
string prefixPlusCur=prefix+tmp;
if(dict.count(prefixPlusCur))
{
prefix.push_back(cur);
}
else
{
fwrite(&dict[prefix],sizeof(CODE),1,fDest);
dict[prefixPlusCur]=num;
num++;
prefix=tmp;
}
};
fwrite(&dict[prefix],sizeof(CODE),1,fDest);
fclose(fSrc);
fclose(fDest);
return true;
}
template <class CODE>
bool Lzw<CODE>::Decode(const string &src,const string &dest)
{
//dict 初始化
map<CODE,string> dict;
CODE num=0;
for(num=0;num<128;num++)
{
string newItem(1,char(num));
dict[num]=newItem;
}
FILE *fin=fopen(src.c_str(),"rb");
ofstream outfile;
outfile.open(dest.c_str(),ofstream::out);
CODE cur;
fread(&cur,sizeof(CODE),1,fin);
outfile<<dict[cur];
while(true)
{
CODE pre=cur;
fread(&cur,sizeof(CODE),1,fin);
if(feof(fin)) break;
string p=dict[pre];
if(dict.count(cur))
{
outfile<<dict[cur];
string c(1,dict[cur][0]);
dict[num]=p+c;
num++;
}
else
{
string c(1,dict[pre][0]);
dict[num]=p+c;
outfile<<dict[num];
num++;
}
}
fclose(fin);
return true;
}
int main ()
{
string src("d:\\Wind.txt");
string dest("d:\\Gone.lzw");
string test("d:\\Wizard.txt");
Lzw<unsigned short>::Encode(src,dest);
Lzw<unsigned short>::Decode(dest,test);
return 0;
}
//结果截图
//还是不如ZIP...