C++ LZW解压c++;
我试图编写一个lzw数据压缩程序/解压程序,br/>C++ LZW解压c++;,c++,lzw,C++,Lzw,我试图编写一个lzw数据压缩程序/解压程序,br/>,所以我确实使用了一个压缩程序(似乎可以工作,但可能没有),但当我尝试解压它时,我得到了一个奇怪的结果,看起来一点都不像原始文件… 我认为我的错误在于我从文件中获取和/或使用数据的方式,但我不确定……因此,以下是我用于压缩和解压缩的函数,当然欢迎任何批评/问题 编辑:给出一个MCVE 正在压缩的输入文本文件包含:banana_bandana 结果减压者减压者方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方
,所以我确实使用了一个压缩程序(似乎可以工作,但可能没有),但当我尝试解压它时,我得到了一个奇怪的结果,看起来一点都不像原始文件…
我认为我的错误在于我从文件中获取和/或使用数据的方式,但我不确定……因此,以下是我用于压缩和解压缩的函数,当然欢迎任何批评/问题 编辑:给出一个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;
}
}
使用编码=uint16\t;
#定义最大值4096//2^12
静态int代码=0;
字符串组合(字符串s、字符c){
s+=c;
返回s;
}
字符串findkey(无序地图和Dico,int val){
字符串键;
字符串为空;
无序映射::常量迭代器;
for(it=Dico.begin();it!=Dico.end();+it){
if(it->second==val){
key=it->first;
返回键;
}else{返回空;}
}
}
字符串findkey2(无序映射和Dico,编码val){
字符串键;
字符串为空;
无序映射::常量迭代器;
for(it=Dico.begin();it!=Dico.end();+it){
if(it->second==val){
key=it->first;
返回键;
}else{返回空;}
}
}
无效初始Dico(无序映射和Dico){
Dico.clear();
字符串s=“”;
字符c;
用于(代码=0;代码<256;代码++)
{
c=(char)代码;
s+=c;
Dico[s]=代码;
s、 清除();
}
}
void InitDico2(无序映射和Dico){
Dico.clear();
字符串s=“”;
字符c;
用于(代码=0;代码<256;代码++)
{
c=(char)代码;
s+=c;
编码sizeplus=Dico.size();
Dico[s]=sizeplus;
s、 清除();
}
}
空隙压缩(ifstream&is、ofstream&of){
无序地图Dico;
InitDico(Dico);
字符串s=“”;
字符c;
while(is.get(c)){
如果(Dico.size()=最大值){
InitDico(Dico);
}
如果(Dico.计数(组合(s,c))){
s+=c;
}否则{
插入({(组合(s,c)),代码});
代码++;
of.write(重新解释转换(&Dico.at)),sizeof(代码));
s=c;
}
}
of.write(重新解释转换(&Dico.at)),sizeof(代码));
}
空隙压缩2(如果流和is、流和of){
无序地图Dico;
二氧化二镉(Dico);
字符串s=“”;
字符c;
int max=数值限制::max();
while(is.get(c)){
如果(Dico.size()=最大值){
二氧化二镉(Dico);
}
如果(Dico.计数(组合(s,c))){
s+=c;
}否则{
编码sizeplus=Dico.size();
Dico[{(combi(s,c))}]=sizeplus;
of.write(reinterpret_cast(&Dico.at(s))、sizeof(Encoding));
s=c;
}
}
of.write(reinterpret_cast(&Dico.at(s))、sizeof(Encoding));
}
真空减压(ifstream&is、ofstream&of){
无序地图Dico;
InitDico(Dico);
字符串s,prevstring;
字符c;
int prevcode,currcode;
is.read(reinterpret_cast(&prevcode),sizeof(prevcode));
s=findkey(Dico,prevcode);
of.write(重新解释铸件),尺寸f(s));
while(is.read(reinterpret_cast(&currcode),sizeof(currcode))){
s=findkey(Dico,currcode);
of.write(重新解释铸件),尺寸f(s));
c=s[0];
prevstring=findkey(Dico,prevcode);
插入({(组合(prevstring,c)),代码});
prevcode=当前代码;
}
}
void decompress2(ifstream&is,of stream&of){//使用uint16和另一种算法进行解压缩
无序地图Dico;
二氧化二镉(Dico);
编码n;
is.read(重新解释铸造(&n),sizeof(n));
字符串v=findkey2(Dico,n);
字符串w;
字符串输入;
of.write(重新解释类型(&v),sizeof(v));
w=v;
while(is.read(reinterpret_cast&n),sizeof(n))){
v=findkey2(Dico,n);
如果(Dico.计数(v)){
入口=v;
}else{entry=combi(w,w[0]);}
of.write(reinterpret_cast(&entry),sizeof(entry));
编码sizeplus=Dico.size();
Dico[combi(w,条目[0])]=sizeplus;
w=输入;
}
}
我看到的一个问题是,当您将解压缩数据写入文件时,您写入的是字符串对象,而不是对象中包含的字符串数据。要做到这一点,您需要获取对象所持有的数据。在解压中
,用
of.write(s.c_str(), s.length());
类似的更改需要在
decompress2
(两次)中进行。除非您正在为压缩、加密等发明新的算法,否则通常最好使用预先存在的实现。如果你环顾四周,有许多图书馆很容易得到。@ ReMyLeBeAI并不是真的试图用它来学习它,而是一种学习C++的方法,它看起来像是一个简单的代码算法……你所编码的数据与任何能解压LZW的工具都能正确解压吗?请提供示例输入和输出。您当前得到的结果以及为什么与预期结果不匹配。当我读到你的问题时,你基本上是在问“我是否正确实施了链接中显示的流程?”这是一个没有MCVE的问题。@DavidC.Rankin很抱歉给你带来不便,如果你有任何想法让我的帖子更清晰易读,请提问。