Codifica Huffman: perché non è necessario un separatore?


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

Testo originale:

Occhi inquietanti visti vicino al lago

Codificato:
0000101100000110011100010101101101001111101011111100011001111110100100101

Perché non è necessario un separatore nella codifica Huffman?


1
Perché quando decodifichi un valore binario, prendi la porzione di bit "da sinistra a destra", a seconda di quale valore corrisponde prima al valore del testo originale. Come in questo caso, vedi il blocco più a sinistra (0000) corrisponde a E. Se ci fosse un simbolo con un valore di 000 nel tuo codice char, sostituiresti 000 con quel simbolo e ricominceresti a cercare nuovamente dai bit rimanenti in un modo "da sinistra a destra". Ecco perché non hai bisogno di alcuna separazione.
Syed Ali Hamza,

1
La domanda implica che i separatori sono generalmente necessari. Sai già che non hai bisogno di separatori Eerie eyes seen near lake(beh, tranne per il carattere spazio). Ma i personaggi stessi non hanno bisogno di separatori. Perché non è quello?
Salterio

prova a decodificarlo da solo, non c'è mai alcuna ambiguità.
njzk2,

@MSalters: di solito sono necessari separatori con parole di lunghezza variabile: cat cheat for micecatch eat form ice. La tua analogia è imperfetta: ogni lettera è atomica; le lettere sono banalmente distinte e intrinsecamente separabili. Un'analogia migliore sarebbe "Perché riesci a leggere lo script corsivo (scritto a mano), quando ogni parola è solo una riga lunga, accecante, autointersecante?", E anche quella è una povera analogia, dal momento che puoi guardare una parola scritta a mano ( o anche una parte di uno) e discernere le singole lettere, mentre una stringa codificata da Huffman è incomprensibile se non riesci a vedere l'inizio.
G-Man dice "Ripristina Monica" il

@MSalters Non vedo il tuo punto. Non ho bisogno di separatori per i personaggi perché stiamo usando una codifica a larghezza fissa: ogni blocco successivo di otto bit corrisponde a un carattere. Ma la codifica di Huffman non è a larghezza fissa, quindi la domanda.
David Richerby,

Risposte:


50

Non è necessario un separatore perché i codici Huffman sono codici privi di prefisso (anche, inutilmente, noti come "codici prefisso"). Ciò significa che nessuna codeword è un prefisso di qualsiasi altra codeword. Ad esempio, la parola in codice per "e" nel tuo esempio è 10 e puoi vedere che nessun altra parola in codice inizia con le cifre 10.

Ciò significa che puoi decodificare avidamente leggendo la stringa codificata da sinistra a destra e producendo un carattere non appena hai visto una parola in codice. Ad esempio, 0, 00 e 000 non codificano nulla, quindi continui a leggere i bit. Quando leggi 0000, codifica "E" e, poiché il codice è privo di prefissi, sai che non esiste un'altra parola chiave 0000x, quindi ora puoi generare "E" e iniziare a leggere la parola chiave successiva. Ancora una volta, 1 non codifica nient'altro che 10 codifica "e". Nessun altro codice inizia con "10", quindi puoi generare "e". E così via.


1
I codici prefisso sono anche comunemente noti come Codici istantanei (vedi ad esempio, Elements of Information Theory di Cover & Thomas). Penso che il termine prefisso codice venga molto più spesso del prefisso libero.
Batman,

3
Vale anche la pena ricordare che, al fine di decodificare una sequenza di codici Huffman concatenati, si deve innanzitutto fornire il limite corretto della parola chiave. Se si tenta di decodificare la sequenza con un limite di parola in codice errato, il processo di decodifica genererà una sequenza errata di simboli di output.
rwong,

@rwong: se il codice Huffman si avvia in modo errato sincronizzato, può continuare a generare indefinitamente simboli errati, ma ogni volta che determina erroneamente la lunghezza di un simbolo, il numero di possibili stati errati verrà ridotto.
supercat,

@supercat Immagino che lo esprimerei in un modo diverso: se un decodificatore Huffman è inizialmente impostato su un limite di parole in codice errato e inizia l'elaborazione, c'è una possibilità (che può essere zero o altro e può dipendere sia dal dizionario che dal bit stream content) che potrebbe atterrare su un limite di codeword corretto per coincidenza a tempo finito, e quando ciò accadrà produrrà il risultato di decodifica corretto per i simboli successivi. Sono state condotte alcune ricerche sulle proprietà (sul dizionario delle parole chiave e sul flusso di bit) che avrebbero garantito questa risincronizzazione.
rwong,

@rwong: se i dati originali fossero casuali con una distribuzione tale che i bit del flusso avessero ciascuno una probabilità indipendente di essere uno o zero, la probabilità di rimanere fuori sincrono per più di N simboli decadrebbe esponenzialmente all'aumentare di N. È più probabile che i dati effettivi contengano schemi che potrebbero impedire la risincronizzazione, ma in pratica è improbabile che un errore all'inizio di un file di testo da 100 MB danneggi tutti i 100 MB di testo.
supercat

13

È utile immaginarlo come un albero. Stai semplicemente attraversando l'albero fino a quando non colpisci un nodo foglia e quindi riavvii dalla radice. Dall'algoritmo che esegue la codifica huffman, puoi vedere che questo tipo di struttura viene creata nel processo.

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


6
L'aspetto importante qui è che tutte le parole in codice valide sono foglie. Avresti bisogno di separatori se avessi simboli anche su nodi interni.
MvG,

3

Nessun codice diverso da E inizia con 0000. Nessun codice diverso da I inizia con 0001. E così via. Come caso estremo, nessun codice diverso da e inizia con 01. Non hai cose come E = 0000, spazio = 000, dove non sapresti cosa fare se trovi tre zeri.

Guarda la tua stringa codificata: 0000101100000 ...

Hai letto il primo zero. Sai che il codice è uno di E, i, y, l, k, virgola o spazio. Lo zero successivo significa che non è k, virgola o spazio, ma E, i, y o l. Lo zero successivo significa che è E o i. Lo zero successivo significa che è un E. Quando sai quale codice è, sai di aver analizzato tutti i bit per quel codice.

Quindi hai 101100000 ... Il 1 significa che hai e, r, s, n o a. Il bit successivo è 0, quindi il codice è e. Ancora una volta, hai finito con quel personaggio.


-2

Non possiamo usare il separatore nella codifica Huffman perché l'equivalente binario di ogni lettera non corrisponde al codice prefissato di nessuna lettera, quindi possiamo fare a meno di usare anche il separatore.


3
Non l'ho già detto, solo senza i livelli confusi di molte negazioni annidate. (E, a proposito, non è che non possiamo usare un separatore; solo che non ne abbiamo bisogno .)
David Richerby,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.