我正在尝试对lzw数据压缩器/解压缩器进行编码,br />
所以我确实使用this Algorithm制作了一个压缩器(似乎可以正常工作,但可能无法工作),但是当我尝试进行解压缩时我得到一个奇怪的结果,根本不像原始文件一样...
我认为我的错误在于我从文件中获取和/或使用数据的方式,但是我不确定……所以这里是我用来压缩和解压缩的函数,当然,欢迎任何批评家/问题。
编辑:给出MCVE
输入文本文件被压缩,包含:banana_bandana
减压输出结果:ì# #ü#ìû#ÿ#ü#ì##ÿ#ü#
编辑2:所有有用的功能来重现输出:
using Encoding = uint16_t;
#define MAX 4096 //2^12
static int code = 0;
string combi (string s , char c ){
s += c ;
return s;
}
string findkey(unordered_map<string, int>& Dico , int val ){
string key ;
string empty ;
unordered_map<string, int>::const_iterator it;
for (it = Dico.begin(); it != Dico.end(); ++it){
if (it->second == val){
key = it->first;
return key;
}else {return empty;}
}
}
string findkey2(unordered_map<string, Encoding>& Dico , Encoding val ){
string key ;
string empty ;
unordered_map<string, Encoding>::const_iterator it;
for (it = Dico.begin(); it != Dico.end(); ++it){
if (it->second == val){
key = it->first;
return key;
}else {return empty;}
}
}
void InitDico (unordered_map<string, int>& Dico) {
Dico.clear();
string s = "";
char c;
for (code = 0; code < 256; code++)
{
c = (char)code;
s += c;
Dico[s] = code;
s.clear();
}
}
void InitDico2 (unordered_map<string, Encoding>& Dico) {
Dico.clear();
string s = "";
char c;
for (code = 0; code < 256; code++)
{
c = (char)code;
s+= c;
Encoding sizeplus = Dico.size();
Dico[s] = sizeplus;
s.clear();
}
}
void compress(ifstream &is, ofstream &of){
unordered_map<string,int> Dico ;
InitDico(Dico);
string s = "";
char c ;
while(is.get(c)){
if(Dico.size() == MAX){
InitDico(Dico);
}
if(Dico.count(combi(s,c))){
s += c;
}else{
Dico.insert({(combi(s,c)),code});
code ++;
of.write(reinterpret_cast<const char *> (&Dico.at(s)),sizeof(code));
s = c;
}
}
of.write(reinterpret_cast<const char *> (&Dico.at(s)),sizeof(code));
}
void compress2(ifstream &is, ofstream &of){
unordered_map<string,Encoding> Dico ;
InitDico2(Dico);
string s = "";
char c ;
int max = numeric_limits<Encoding>::max();
while(is.get(c)){
if(Dico.size() == max){
InitDico2(Dico);
}
if(Dico.count(combi(s,c))){
s += c;
}else{
Encoding sizeplus = Dico.size();
Dico[{(combi(s,c))}] = sizeplus;
of.write(reinterpret_cast<const char *> (&Dico.at(s)),sizeof(Encoding));
s = c;
}
}
of.write(reinterpret_cast<const char *> (&Dico.at(s)),sizeof(Encoding));
}
void decompress(ifstream &is, ofstream &of){
unordered_map<string,int> Dico ;
InitDico(Dico);
string s , prevstring;
char c ;
int prevcode,currcode ;
is.read(reinterpret_cast<char *>(&prevcode),sizeof(prevcode));
s = findkey(Dico,prevcode);
of.write(reinterpret_cast<const char *> (&s) , sizeof(s));
while(is.read(reinterpret_cast<char *>(&currcode),sizeof(currcode))){
s = findkey(Dico,currcode);
of.write(reinterpret_cast<const char *> (&s) , sizeof(s));
c =s[0];
prevstring = findkey(Dico,prevcode);
Dico.insert({(combi(prevstring,c)),code});
prevcode = currcode;
}
}
void decompress2(ifstream &is, ofstream &of){//Decompression using uint16 and another algorithm
unordered_map<string,Encoding> Dico ;
InitDico2(Dico);
Encoding n ;
is.read(reinterpret_cast<char*>(&n),sizeof(n));
string v = findkey2(Dico,n);
string w ;
string entry;
of.write(reinterpret_cast<const char *> (&v) , sizeof(v));
w = v ;
while(is.read(reinterpret_cast<char *>(&n),sizeof(n))){
v = findkey2(Dico,n);
if (Dico.count(v)){
entry = v ;
}else{entry = combi(w,w[0]);}
of.write(reinterpret_cast<const char *> (&entry) , sizeof(entry));
Encoding sizeplus = Dico.size();
Dico[combi(w,entry[0])]=sizeplus;
w = entry;
}
}
答案 0 :(得分:1)
我看到的一个问题是,当您将解压缩的数据写到文件中时,您写的是字符串 object ,而不是对象中包含的字符串 data 。为此,您需要获取对象保存的数据。在decompress
中,将您所有的写入都替换为
of.write(s.c_str(), s.length());
decompress2
中需要进行类似的更改(两次)。