허프만 인코딩 : 왜 구분자가 필요하지 않습니까?


17
Char        Code
====        ====
E           0000
i           0001
y           0010
l           0011
k           0100
.           0101
space       011
e           10
r           1100
s           1101
n           1110
a           1111

원문 :

호수 근처에서 본 섬뜩한 눈

인코딩 :
0000101100000110011100010101101101001111101011111100011001111110100100101

허프만 인코딩에서 구분 기호가 필요하지 않은 이유는 무엇입니까?


1
이진 값을 디코딩 할 때 원래 텍스트의 값과 먼저 일치하는 비트의 "왼쪽에서 오른쪽으로"비트를 가져옵니다. 이 경우와 같이 가장 왼쪽 청크 (0000)가 E와 일치하는 것을 볼 수 있습니다. 문자 코드에 값이 000 인 기호가있는 경우 000을 해당 기호로 바꾸고 나머지 비트에서 다시 검색하기 시작합니다. "왼쪽에서 오른쪽으로"방식. 따라서 분리 할 필요가 없습니다.
— Syed Ali Hamza

1
문제는 일반적으로 구분 기호가 필요하다는 것을 암시합니다. 이미 Eerie eyes seen near lake공백 문자를 제외하고는 구분 기호가 필요하지 않다는 것을 이미 알고 있습니다 . 그러나 문자 자체에는 구분 기호가 필요하지 않습니다. 왜 그렇지 않습니까?
— MSalters

그것을 직접 해독하려고하면 모호성이 없습니다.
— njzk2

@MSalters : 그러나 일반적으로 가변 길이 단어 : ≠ 와 구분 기호 가 필요합니다 . 당신의 비유에는 결함이 있습니다 : 각 글자는 원자 적입니다. 글자는 사소하게 구별되고 본질적으로 분리 가능합니다. 더 나은 비유는 "각 단어가 하나의 길고 구불 구불 한 자체 교차 선일 때 필기체 (필기) 스크립트를 읽을 수있는 이유는 무엇입니까?"입니다. 허프만으로 인코딩 된 문자열은 시작 부분을 볼 수 없다면 횡설수설입니다. cat cheat for micecatch eat form ice
— G-Man, 'Reinstate Monica'라고

@MSalters 나는 당신에게 지적하지 않습니다. 고정 너비 인코딩을 사용하기 때문에 문자 구분 기호가 필요하지 않습니다. 8 비트의 각 연속 블록은 하나의 문자에 해당합니다. 그러나 허프만 코딩은 고정 폭이 아니기 때문에 문제가됩니다.
— David Richerby

답변:


50

허프만 코드는 접두사가없는 코드 ( "접두어 코드"라고도 함)로 구분 기호가 필요하지 않습니다. 이것은 다른 코드 워드의 접두사가 코드 워드가 아님을 의미합니다. 예를 들어, 예제에서 "e"의 코드 워드는 10이며 숫자 10으로 시작하는 다른 코드 워드가 없음을 알 수 있습니다.

즉, 인코딩 된 문자열을 왼쪽에서 오른쪽으로 읽고 코드 워드를 보자 마자 문자를 출력하여 탐욕스럽게 디코딩 할 수 있습니다. 예를 들어, 0, 00 및 000은 아무것도 코딩하지 않으므로 비트를 계속 읽습니다. 0000을 읽을 때 "E"를 인코딩하고 코드에 접두사가없는 코드이므로 다른 코드 워드 0000x가 없다는 것을 알고 있으므로 이제 "E"를 출력하고 다음 코드 워드를 읽을 수 있습니다. 다시 말하지만, 1은 10을 제외한 다른 어떤 것도 인코딩하지 않습니다. 다른 코드 워드는 "10"으로 시작하지 않으므로 "e"를 출력 할 수 있습니다. 등등.


1
접두사 코드는 일반적으로 순간 코드라고도합니다 (예 : Cover & Thomas의 정보 이론 요소 참조). 프리픽스 코드라는 용어는 프리픽스 프리 코드보다 훨씬 자주 나온다고 생각합니다.
— 배트맨

3
일련의 연결된 허프만 코드를 디코딩하려면 먼저 올바른 코드 워드 경계를 지정해야합니다. 잘못된 코드 워드 경계에서 시퀀스를 디코딩하려고하면 디코딩 프로세스에서 잘못된 출력 심볼 시퀀스가 ​​생성됩니다.
— rwong

@rwong : 허프만 코드가 잘못 동기화 된 것으로 시작되면 잘못된 기호를 무기한으로 계속 출력 할 수 있지만, 기호의 길이를 잘못 결정하면 언제든지 잘못된 상태의 수가 줄어 듭니다.
— supercat

@supercat 나는 다른 방식으로 그것을 표현할 것 같다 : 허프만 디코더가 처음에 잘못된 코드 워드 경계에 설정되어 처리를 시작하면 가능성이있을 수 있습니다 (0 또는 아무것도있을 수 있으며 사전과 사전에 따라 다를 수 있음) 비트 스트림 콘텐츠)를 선택하면 유한 시간 내에 우연의 일치로 올바른 코드 워드 경계에 도달 할 수 있으며,이 경우 후속 심볼에 대해 올바른 디코딩 결과가 생성됩니다. 이 재 동기화를 보장하는 속성 (코드 워드 사전 및 비트 스트림)에 대한 연구가있었습니다.
— rwong

@rwong : 스트림의 비트가 각각 독립적으로 1 또는 0의 확률을 갖도록 원본 데이터가 분포에 무작위 인 경우, N보다 많은 심볼에 대해 동기화되지 않은 채로 남을 확률은 N이 증가함에 따라 기하 급수적으로 감소합니다. 실제 데이터에는 재 동기화를 방해 할 수있는 패턴이 포함되어있을 가능성이 높지만 실제로 100MB 텍스트 파일 시작시 오류로 인해 100MB의 텍스트가 모두 손상 될 가능성은 거의 없습니다.
— supercat

13

그것을 나무로 상상하면 도움이됩니다. 리프 노드에 도달 할 때까지 트리를 순회 한 다음 루트에서 다시 시작합니다. 허프만 코딩을 수행하는 알고리즘에서 이러한 종류의 구조가 프로세스에서 생성되었음을 알 수 있습니다.

https://en.wikipedia.org/wiki/File:HuffmanCodeAlg.png


6
여기서 중요한 측면은 모든 유효한 코드 단어가 리프라는 것입니다. 내부 노드에도 기호가 있으면 구분 기호가 필요합니다.
— MvG

3

E 이외의 코드는 0000으로 시작하지 않습니다. i 이외의 코드는 0001로 시작하지 않습니다. 극단적 인 경우, e 이외의 코드는 01로 시작하지 않습니다. E = 0000, space = 000과 같은 것은 없으며 세 개의 0을 찾으면 어떻게해야할지 알 수 없습니다.

인코딩 된 문자열을보십시오 : 0000101100000 ...

첫 번째 0을 읽습니다. 코드가 E, i, y, l, k, 쉼표 또는 공백 중 하나임을 알고 있습니다. 다음 0은 k, 쉼표 또는 공백이 아니라 E, i, y 또는 l임을 의미합니다. 다음 0은 E 또는 i임을 의미합니다. 다음 0은 E임을 의미합니다. 어떤 코드인지 알면 해당 코드의 모든 비트를 파싱 한 것입니다.

그러면 101100000이 있습니다. 1은 e, r, s, n 또는 a를 의미합니다. 다음 비트는 0이므로 코드는 e입니다. 다시 말하지만, 당신은 그 캐릭터로 끝났습니다.


-2

모든 문자의 이진 문자가 모든 문자의 접두사 코드와 일치하지 않으므로 Huffman 인코딩에서 구분 기호를 사용할 수 없으므로 구분 기호를 사용하지 않아도 할 수 있습니다.


3
나는 많은 중첩 된 부정의 혼란스러운 수준이없는 경우에만 이미 그렇게 말하지 않았습니다. (그리고 그건 우리 가 구분 기호를 사용할 수있는 것이 아니라 필요 하지 않습니다 .)
— David Richerby
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.