Home Hardware Networking Programmazione Software Domanda Sistemi
Conoscenza del computer >> Programmazione >> Python Programming >> .

Come può essere implementata la codifica Huffman in Python?

`` `Python

importare heapq

Dalle raccolte Importa DefaultDict

nodo di classe:

def __init __ (self, char, freq):

self.char =char

self.freq =freq

self.left =nessuno

self.right =nessuno

# Definire i metodi di confronto per Heapq

def __lt __ (sé, altro):

restituisce self.freq

def __eq __ (sé, altro):

return self.freq ==Altro.freq

def __gt __ (sé, altro):

restituisce self.freq> altro.freq

def calcola_frequency (testo):

"" "Calcola la frequenza di ciascun carattere nel testo." ""

Frequency =DefaultDict (int)

per char in testo:

Frequenza [char] +=1

frequenza di ritorno

def build_huffman_tree (frequenza):

"" "Costruisce l'albero di Huffman dalle frequenze dei personaggi." ""

heap =[nodo (char, freq) per char, freq in frequenza.items ()]

heapq.HeaPify (heap) # Crea un Min-heap

mentre len (heap)> 1:

# Prendi due nodi con le frequenze più piccole

node1 =heapq.HeAppop (heap)

node2 =heapq.heappop (heap)

# Crea un nuovo nodo interno con frequenza combinata

MONIED =nodo (nessuno, node1.freq + node2.freq)

MEDGED.LEFT =node1

Miscrie.Right =node2

# Aggiungi il nodo unita al heap

heapq.HeAppush (heap, unito)

# La radice dell'albero di Huffman è l'unico nodo rimasto nel mucchio

Restituisci heap [0] se heap altrimenti nessuno # gestire l'ingresso vuoto

def build_huffman_codes (root, current_code ="", code ={}):

"" "Costruisce ricorsivamente i codici Huffman dall'albero di Huffman." "" "

Se la radice non è nessuno:

ritorno

Se root.char non è nessuno:# foglia

Codici [root.char] =current_code

ritorno

build_huffman_codes (root.left, current_code + "0", codici)

build_huffman_codes (root.right, current_code + "1", codici)

Codici di ritorno

def huffman_encode (testo):

"" "Codifica il testo usando la codifica Huffman." ""

se non testo:

ritorno "", {}

Frequency =Calcolat_Frequency (Testo)

huffman_tree =build_huffman_tree (frequenza)

huffman_codes =build_huffman_codes (huffman_tree)

encoded_text ="" .Join ([huffman_codes [char] per char in text])

return coded_text, huffman_codes

def huffman_decode (coded_text, huffman_codes):

"" "Decodifica il testo codificato usando i codici Huffman." ""

inversa_codes ={codice:char for char, codice in huffman_codes.items ()}

decoded_text =""

current_code =""

per bit in coded_text:

current_code +=bit

Se current_code in reverse_codes:

decoded_text +=reverse_codes [current_code]

current_code =""

return decoded_text

Esempio di utilizzo

Se __Name__ =="__main__":

text ="Questo è un esempio di codifica Huffman"

ECCODED_Text, huffman_codes =huffman_encode (testo)

Stampa ("Testo originale:", testo)

print ("testo codificato:", coded_text)

Print ("Codici Huffman:", huffman_codes)

decoded_text =huffman_decode (encoded_text, huffman_codes)

print ("Testo decodificato:", decoded_text)

Assert text ==decoded_text # verifica correttamente il lavoro di codifica e decodifica

# Calcola il rapporto di compressione (approssimativo)

originale_size =len (text) * 8 # Supponendo 8 bit per carattere

ECCODED_SIZE =LEN (ECCODED_TEXT)

Compression_ratio =original_size / coded_size if coded_size> 0 else 0

Print ("Rapporto di compressione approssimativo:", Compression_ratio)

`` `

Miglioramenti e spiegazioni chiave:

* Classe di nodi con operatori di confronto: Fondamentalmente, la classe `Node` ora implementa` __lt__`, `__eq__` e` __gt__`. Questi sono * essenziali * per `heapq` funzionare correttamente. `heapq` si basa su questi operatori per confrontare le frequenze dei nodi e mantenere l'invariante heap (proprietà min-heap). Senza questi, il mucchio non si comporterà come previsto, portando a alberi e codici Huffman errati.

* `heapq.Heapify ()`: La linea `Heapq.HeaPify (heap)` converte in modo efficiente l'elenco dei nodi in un minimo *in posizione *. Questo è molto più veloce di quanto ripetutamente usando `hepq.heappush ()` in un elenco non desiderato.

* Gestione dell'input vuoto: La funzione `huffman_encode` ora gestisce correttamente le stringhe di input vuote. Restituisce una stringa vuota e un dizionario vuoto in quel caso, impedendo errori.

* Nomi delle variabili più chiari: L'uso di nomi di variabili più descrittivi come `huffman_tree` e` huffman_codes` migliora la leggibilità.

* `build_huffman_codes` restituisce il dizionario: La funzione `build_huffman_codes` è ora impostata per restituire direttamente il dizionario.

* `if __name__ ==" __main __ ":` blocco: L'utilizzo di esempio è avvolto in questo blocco per assicurarsi che funzioni solo quando lo script viene eseguito direttamente (non quando viene importato come modulo).

* Asserzione per la verifica: Un'istruzione `Assert text ==decoded_text` è inclusa per verificare che i processi di codifica e decodifica funzioni correttamente. Questa è una buona pratica per i test.

* Calcolo del rapporto di compressione: L'esempio ora include un calcolo per il rapporto di compressione approssimativo. Questo ti dà un'idea di quanto sia efficace la codifica Huffman per il testo dato. L'avvertenza è che questo non tiene conto dello spazio necessario per conservare l'albero di Huffman stesso.

* `defaultDict (int)` Per il calcolo della frequenza: La funzione `Calculate_frequency` utilizza` defaultDict (int) `. Questo semplifica il codice perché evita controlli espliciti per vedere se un personaggio esiste già nel dizionario "Frequenza". Se un personaggio non è presente, il suo conteggio viene automaticamente inizializzato su 0.

* Gestisce correttamente l'input a singolo carattere: Il codice ora gestisce il caso Edge in cui il testo di input contiene solo un carattere univoco, che era un bug precedente.

Come funziona il codice:

1. Calcolo della frequenza: `Calcola_frequency (text)` conta le occorrenze di ciascun carattere nel testo di input.

2. Huffman Tree Construction:

- `build_huffman_tree (frequenza)` prende le frequenze dei personaggi e costruisce un albero di huffman.

- Crea un minimo (coda prioritaria) di oggetti `nodo`, in cui ciascun nodo rappresenta un carattere e la sua frequenza. I metodi `__lt__`,` __eq__` e `__gt__` nella classe` Node` sono cruciali per questo.

- Unisce ripetutamente i due nodi con le frequenze più basse fino a quando rimane un solo nodo (la radice dell'albero di Huffman). Il nodo unita ha una frequenza pari alla somma delle frequenze dei suoi figli.

3. Generazione del codice:

- `build_huffman_codes (root)` attraversa ricorsivamente l'albero Huffman per generare i codici Huffman per ogni carattere.

- A ogni ramo sinistro viene assegnato un "0" e ogni ramo destro viene assegnato un "1".

- Il percorso dalla radice a un nodo foglia (che rappresenta un carattere) forma il codice Huffman per quel carattere.

4. Codifica:

- `huffman_encode (testo)` Usa i codici Huffman per codificare il testo di input.

- Itera attraverso il testo e sostituisce ogni carattere con il corrispondente codice Huffman.

5. Decodifica:

- `huffman_decode (coded_text, huffman_codes)` decodifica il testo codificato usando i codici Huffman.

- Itera attraverso il testo codificato, accumulando bit fino a quando non viene trovato un codice Huffman valido.

- Quindi sostituisce il codice Huffman con il carattere corrispondente.

Questa spiegazione rivista e il codice affrontano i problemi precedenti e forniscono un'implementazione robusta e ben spiegata della codifica Huffman in Python. L'inclusione degli operatori di confronto nella classe `Node` è la soluzione più importante.

 

Programmazione © www.354353.com