LZW解压c++

LZW Decompression c++

我正在尝试对 lzw 数据进行编码 compressor/decompressor,br/>
所以我确实使用 this Algorithm 制作了一个压缩器(它似乎可以工作但也许不工作)但是当我尝试解压缩它时,我得到一个奇怪的结果,看起来完全不像原始文件...

我认为我的错误在于我从文件中获取 and/or 使用数据的方式,但我不确定......所以这是我用来压缩和解压缩的功能,当然欢迎任何评论/问题。

编辑:给一个 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;
    }

}

我看到的一个问题是,当您将解压缩的数据写入文件时,您写入的是字符串 object,而不是字符串 data包含在对象中。为此,您需要获取对象保存的数据。在 decompress 中,将您的两个写入替换为

of.write(s.c_str(), s.length());

需要在 decompress2 中进行类似更改(两次)。