2014-10-13 7 views
0

허프만 코딩을 구현했습니다 (연구 과제 임). 일부 텍스트 문자열을 입력으로 가져오고 "011010 00101 0110 0101 0110 0101 0111 0000 0010 0000 0110 0010 0110 1111 0110 1111 0111 0000 0010 0000 0110 0010 0110 0101 0110"과 같은 결과 문자열을 생성합니다.크기를 줄이기 위해 문자열을 이진 데이터로 변환하는 방법이 있습니까?

string some_text = read_text_file_to_string(text_file); 

string coded_string = encode_string(some_text); // coded_string == "011010 00101 0110 0101..." 

바이너리 형식으로 coded_string 변환하고 파일에 쓸 수있는 방법이 있습니까? 내 목표는 입력 데이터의 크기를 줄이는 것입니다. 그러나, 파일에 coded_string을 쓰면 파일이 더 커집니다.

+1

std :: bitset를 사용할 수 있습니까? – Niall

+4

일반적으로 전체 바이트가있을 때까지 비트를 누적 한 다음 바이트를 디스크에 씁니다. 다시 읽어 들일 때 한 번에 전체 바이트를 읽고 트리의 리프에 도달했을 때의 현재 비트 그룹에 얼마나 많은 비트가 있는지 파악합니다. 맨 마지막에 전체 바이트를 얻기 위해 일부 패딩을 추가해야 할 수도 있습니다. –

+0

@ 닐, 예, 할 수 있습니다. 그러나 비트 셋을 돕기 위해 데이터 크기를 줄이는 방법을 이해하지 못합니다. – Denis

답변

0

공백이 중요하지 않다는 귀하의 의견을 토대로, 나는 0 또는 1 이외의 어떤 것도 무시할 수 있다고 가정 할 것입니다. 이 경우이 함수를 사용하여 파일 스트림에 기록 할 수 있습니다. 마지막 옥텟은 0으로 오른쪽으로 채워질 것입니다. 따라서 입력 된 비트 수가 8로 정확히 나눌 수없는 경우, 어딘가에서 마지막 옥텟의 비트 수를 쓰는 방법으로이를 고려해야합니다. (아마도 데이터 이후).

void write_bits(std::ostream & output, std::string const & input) 
{ 
    unsigned char c; 
    int bits = 0; 

    for (auto i = output.begin(); i != output.end(); ++i) { 
     if (*i == '0' || *i == '1') { 
      c = (c << 2); 
      if (*i == '1') { 
       ++c; 
      } 

      if (++bits == 8) { 
       output << c; 
       c = 0; 
       bits = 0; 
      } 
     } 
    } 

    if (bits > 0) { 
     while (bits < 8) { 
      c <<= 2; 
      ++bits; 
     } 
     output << c; 
    } 
} 

output 매개 변수의 출력을 파일로 작성하는 순서에 std::ofstream 전달하거나는 std::string로 변환 될 수있는 메모리 구조에 데이터를 기입하기위한 std::ostringstream를 사용할 수있다.

+1

출력 행은 다음과 같지 않아야합니다. output << c; ? – rcgldr

+0

허프만 인코딩에는 데이터 코드의 끝에 대한 비트 패턴이 있어야하므로 바이트 (또는 다른 문자) 경계로 채워지므로 데이터 코드 끝에 오는 비트는 모두 무시됩니다. – rcgldr

+0

@rcgldr 사실 그렇습니다. – cdhowie

0

패턴이 항상 4 자이고 그 뒤에 공백이 있으면 8 자리 숫자를 8 자리수 (http://www.wikihow.com/Convert-from-Binary-to-Decimal)의 이진 값으로 변환 할 수 있습니다. 마지막 4 자리 숫자는 실제로 4 또는 8 표현입니다. 하지만 그것은 내가 생각하기에 ...

+0

불행히도, 패턴은 항상 4가 아닙니다. 그것은 나쁜 예입니다. – Denis

+0

문자열의 리갈 문자는 무엇입니까? – yossico

+0

0-1 및 공백은 문자열의 리글 문자입니다. – Denis

0

텍스트 입력을 처리하고 있기 때문에 파일을 사용하더라도 RAM에 전체 파일과 인코딩 된 데이터를 모두 저장할 수있는 충분한 메모리가 있습니다. 텍스트 문자열을 직접 이진 버퍼로 인코딩 한 다음 원본 질문과 같이 이진 버퍼의 허프만 코드를 텍스트 표시 문자열로 변환하는 함수를 만들 수 있습니다.

이진 버퍼 공간을 할당 할 때 최악의 시나리오를 가정합니다. 예를 들어 가장 긴 코드가 12 비트이면 최대 비트 수는 텍스트 파일의 바이트 수인 편리한 경계로 반올림 한 12 x (n + 1)이고 +1이 사용됩니다 데이터 코드의 끝에.

텍스트 파일을 허프만 이진 파일로 인코딩 할 수있는 프로그램과 허프 먼 파일을 텍스트 파일로 디코딩 할 수있는 프로그램을 만드는 것이 유용 할 수 있습니다.

관련 문제