2011-03-02 2 views
1

나는이 알고리즘에 대해 읽고 있었다 ... 그리고 난 아직 압축 해제 클래스를 코딩하지 않은 압축하는 클래스를 코딩?LZ77 - 알고리즘 - 당신이 코드에 대해 어떻게 생각하십니까</p> <p>... 해상도

나는 문제가 생겼다고 생각한다. 나의 성문화는 다음과 같다. "position | length"하지만 위치와 길이의 숫자가 맞는지 알지 못하기 때문에이 방법으로 문제가 풀릴 것이라고 믿는다. ... 2, 3, 4 자리 숫자입니다 : S

몇 가지 조언을 승인은 ... : D

어떤 제안이 허용됩니다.

홈페이지 파일 :

 #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; 
     } 

헤더 파일 :

#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(); 
    } 
    } 
} 

감사합니다!

임은 descompressing 클래스를 코딩 :

+0

'위치 | 길이 | - 또는 길이를 고정 너비 필드로 만드시겠습니까? –

+0

그래, 나도 그걸 생각하고 있었어. 또한 가장 좋은 방법은 파일에 구조가있는 "aleatory file"을 사용하는 것이라고 생각한다. – fpointbin

답변

4

내가 일반적으로 먼저 압축 해제를 작성하고 그것을 일치하도록 압축기를 작성하는 것이 좋습니다.

압축기와 해당 압축 해제기를 먼저 고정 크기 사본 항목으로 작업하고 나중에 필요할 경우 - 가변 크기 사본 항목을 생산/소비하도록 조정하는 것이 좋습니다.

많은 LZ77 형 알고리즘은 압축 파일에서 고정 된 크기를 사용하여 위치와 길이를 나타냅니다. 길이는 한 자리 16 진수이고 위치는 3 자리 16 진수입니다. 합계 2 바이트입니다.

"|" 위치와 복사 길이 사이의 간격은 불필요합니다.

실제로 원래의 LZ77 알고리즘을 구현하려는 경우 압축 알고리즘은 항상 길이가 고정 길이 인 복사 길이 (0 인 경우에도)를 출력해야하며, 고정 길이 위치 (길이가 0 일 때 , 여기에 제로를 붙일 수도 있습니다), 그리고 고정 길이의 리터럴 값입니다.

일부 LZ77 형 파일 형식은 고정 길이 사본 길이, 위치 쌍 또는 하나 이상의 리터럴 값인 "항목"으로 나뉩니다. 당신이 그 길을가는다면, 컴프레서는 어떻게 든 다가오는 아이템이 리터럴 값 (literal value) 또는 복사본 길이 (copy-length) 위치 쌍을 나타내는지를 압축 해제기를 말해야 만합니다. 이렇게하는 많은 방법 중 하나는 출력 압축 해제 된 스트림의 일부 위치를 다른 모든 위치 값과 동일하게 표시하는 대신 입력 압축 파일의 다음 몇 가지 리터럴 값을 나타내는 특수한 "0"위치 값을 예약하는 것입니다.

거의 모든 LZ77 형 알고리즘은 일반 텍스트의 처음부터 전달되는 "위치"가 아니라 현재 위치에서 "오프셋"을 일반 텍스트로 거꾸로 저장합니다. 예를 들어, "1"은 처음 디코딩 된 일반 텍스트 바이트가 아니라 가장 최근에 디코딩 된 일반 텍스트 바이트를 나타냅니다.

압축 된 파일에 일련의 정수가 포함되어있는 경우 어떻게 하나의 정수가 끝나고 다음 정수가 시작되는지 디코더가 알 수 있습니까?

  • 는 각 정수가 얼마나 오래 컴파일시 돌에 설정 한 고정 길이 코드를 사용 3 개 인기 답이 있습니다. (가장 단순한)
  • 가변 길이 코드를 사용하고 "|" 코드 끝을 나타냅니다.
  • 가변 길이 prefix code을 사용하십시오. 범위 코딩 (range coding)과 같은 다른 접근법들도 포함한다. (가장 복잡한)

http://en.wikibooks.org/wiki/Data_Compression

제이콥 지프 아브라함 렘펠; A Universal Algorithm for Sequential Data Compression, IEEE Transactions on Information Theory, 23 (3), pp.337-343, 1977 년 5 월.

관련 문제