C++ LZ77-算法-分辨率
我在读这个算法。。。我编写了一个要压缩的类,我还没有编写解压缩类 你对代码有什么看法 我想我有个问题。。。我的编码是:“位置|长度”,但我相信这种方法会让我在解压不当时遇到问题,因为我不知道位置和长度的数量是否为2、3、4位……: 一些建议将被接受…:D 任何建议都将被接受 主文件:C++ LZ77-算法-分辨率,c++,algorithm,compression,C++,Algorithm,Compression,我在读这个算法。。。我编写了一个要压缩的类,我还没有编写解压缩类 你对代码有什么看法 我想我有个问题。。。我的编码是:“位置|长度”,但我相信这种方法会让我在解压不当时遇到问题,因为我不知道位置和长度的数量是否为2、3、4位……: 一些建议将被接受…:D 任何建议都将被接受 主文件: #include <iostream> #include "Compressor.h" int main() { Compressor c( "
#include <iostream>
#include "Compressor.h"
int main() {
Compressor c( "/home/facu/text.txt", 3);
std::cout << c.get_TEXT_FILE() << std::endl;
std::cout << c.get_TEXT_ENCONDED() << std::endl;
c.save_file_encoded();
return 0;
}
#包括
#包括“压缩机.h”
int main(){
压缩机c(“/home/facu/text.txt”,3);
我通常建议先编写解压器,然后再编写与之匹配的压缩机
我建议先让压缩器和相应的解压器处理固定大小的拷贝项,然后(如果必要的话)调整它们以生成/使用可变大小的拷贝项
许多类似LZ77的算法在压缩文件中使用固定大小来表示位置和长度;
通常一个十六进制数字表示长度,三个十六进制数字表示位置,总共两个字节
位置和复印长度之间不需要“|”
如果你真的想实现原始的LZ77算法,
压缩算法需要始终发出固定长度的拷贝长度(即使它为零)、固定长度位置(当长度为零时,您也可以在此处粘贴零)和固定长度的文字值
一些类似LZ77的文件格式被划分为“项”,这些项可以是固定长度的拷贝长度、位置对,也可以是一个或多个文字值。
如果您这样做,压缩器必须首先告诉解压器即将出现的项是表示文字值还是副本长度、位置对。
实现这一点的许多方法之一是保留一个特殊的“0”位置值,该位置值不是像所有其他位置值一样指示输出解压缩流中的某个位置,而是指示输入压缩文件中接下来的几个文字值
几乎所有类似LZ77的算法都在明文中存储从当前位置向后的“偏移”,而不是从明文开始向前的“位置”。
例如,“1”表示最近解码的明文字节,而不是第一个解码的明文字节
当压缩文件包含一系列整数时,解码器如何判断一个整数的结束位置和下一个整数的开始位置?
有三种流行的答案:
- 使用一个固定长度的代码,在编译时您已经确定了每个整数的长度。(最简单)
- 使用可变长度代码,并保留一个特殊符号,如“|”,以指示代码的结尾
- 使用可变长度
- 其他方法,如距离编码(最复杂)
Jacob Ziv和Abraham Lempel;,IEEE信息论学报,23(3),第337-343页,1977年5月。我通常建议先编写解压器,然后编写压缩机以匹配它
我建议先让压缩器和相应的解压器处理固定大小的拷贝项,然后(如果必要的话)调整它们以生成/使用可变大小的拷贝项
许多类似LZ77的算法在压缩文件中使用固定大小来表示位置和长度;
通常一个十六进制数字表示长度,三个十六进制数字表示位置,总共两个字节
位置和复印长度之间不需要“|”
如果你真的想实现原始的LZ77算法,
压缩算法需要始终发出固定长度的拷贝长度(即使它为零)、固定长度位置(当长度为零时,您也可以在此处粘贴零)和固定长度的文字值
一些类似LZ77的文件格式被划分为“项”,这些项可以是固定长度的拷贝长度、位置对,也可以是一个或多个文字值。
如果您这样做,压缩器必须首先告诉解压器即将出现的项是表示文字值还是副本长度、位置对。
实现这一点的许多方法之一是保留一个特殊的“0”位置值,该位置值不是像所有其他位置值一样指示输出解压缩流中的某个位置,而是指示输入压缩文件中接下来的几个文字值
几乎所有类似LZ77的算法都在明文中存储从当前位置向后的“偏移”,而不是从明文开始向前的“位置”。
例如,“1”表示最近解码的明文字节,而不是第一个解码的明文字节
当压缩文件包含一系列整数时,解码器如何判断一个整数的结束位置和下一个整数的开始位置?
有三种流行的答案:
- 使用一个固定长度的代码,在编译时您已经确定了每个整数的长度。(最简单)
- 使用可变长度代码,并保留一个特殊符号,如“|”,以指示代码的结尾
- 使用可变长度
- 其他方法,如距离编码(最复杂)
Jacob Ziv和Abraham Lempel;,IEEE信息论学报,23(3),第337-343页,1977年5月。像“位置|长度|”这样的编码怎么样?或者把长度作为固定宽度的字段?是的,我在想……我相信最好的方法是使用“假设文件”将结构放入文件中…像“位置|长度|”这样的编码如何?或者将长度设为固定宽度字段?是的,我在想…我还认为最好的方法是使用“任意文件”将结构放入文件中。。。
#ifndef _Compressor_H_
#define _Compressor_H_
#include <utility>
#include <string>
typedef unsigned int T_UI;
class Compressor
{
public:
//Constructor
Compressor( const std::string &PATH, const T_UI minbytes = 3 );
/** GET BUFFERS **/
std::string get_TEXT_FILE() const;
std::string get_TEXT_ENCONDED() const;
/** END GET BUFFERS **/
void save_file_encoded();
private:
/** BUFFERS **/
std::string TEXT_FILE; // contains the text from an archive
std::string TEXT_ENCODED; // contains the text encoded
std::string W_buffer; // contains the string to analyze
std::string W_inspection; // contains the string where will search matches
/** END BUFFERS **/
T_UI size_of_minbytes;
T_UI size_w_insp; // The size of window inspection
T_UI actual_byte;
std::pair< T_UI, T_UI> v_codes; // Values to code text
// Utilitaries functions
void change_size_insp(){ size_w_insp = TEXT_FILE.length() ; }
bool inspection_empty() const;
std::string convert_pair() const;
// Encode algorythm
void lz77_encode();
};
#endif
#include <iostream>
#include <fstream>
using std::ifstream;
using std::ofstream;
#include <string>
#include <cstdlib>
#include <sstream>
#include "Compressor.h"
Compressor::Compressor(const std::string& PATH, const T_UI minbytes)
{
std::string buffer = "";
TEXT_FILE = "";
ifstream input_text( PATH.c_str(), std::ios::in );
if( !input_text )
{
std::cerr << "Can't open the text file";
std::exit( 1 );
}
while( !input_text.eof() )
{
std::getline( input_text, buffer );
TEXT_FILE += buffer;
TEXT_FILE += "\n";
buffer.clear();
}
input_text.close();
change_size_insp();
size_of_minbytes = minbytes;
TEXT_ENCODED = "";
W_buffer = "";
W_inspection = "";
v_codes.first = 0;
v_codes.second = 0;
actual_byte = 0;
lz77_encode();
}
std::string Compressor::get_TEXT_FILE() const
{
return TEXT_FILE;
}
std::string Compressor::get_TEXT_ENCONDED() const
{
return TEXT_ENCODED;
}
bool Compressor::inspection_empty() const
{
return ( size_w_insp != 0 );
}
std::string Compressor::convert_pair() const
{
std::stringstream out;
out << v_codes.first;
out << "|";
out << v_codes.second;
return out.str();
}
void Compressor::save_file_encoded()
{
std::string path("/home/facu/encoded.txt");
ofstream out_txt( path.c_str(),std::ios::out );
out_txt << TEXT_ENCODED << "\n";
out_txt.close();
}
void Compressor::lz77_encode()
{
while( inspection_empty() )
{
W_buffer = TEXT_FILE.substr( actual_byte, 1);
if( W_inspection.find( W_buffer ) == W_inspection.npos )
{
// Cant find any byte from buffer
TEXT_ENCODED += W_buffer;
W_inspection += W_buffer;
W_buffer.clear();
++actual_byte;
--size_w_insp;
}
else
{
// We founded any byte from buffer in inspection
v_codes.first = W_inspection.find( W_buffer );
v_codes.second = 1;
while( W_inspection.find( W_buffer ) != W_inspection.npos )
{
++actual_byte;
--size_w_insp;
v_codes.second++;
W_inspection += TEXT_FILE[actual_byte - 1];
W_buffer += TEXT_FILE[actual_byte];
}
++actual_byte;
--size_w_insp;
if( v_codes.second > size_of_minbytes )
TEXT_ENCODED += convert_pair();
else
TEXT_ENCODED += W_buffer;
W_buffer.clear();
}
}
}