Vitajte na [www.pocitac.win] Pripojiť k domovskej stránke Obľúbené stránky
import hale
Z kolekcií import defaultDict
uzol triedy:
def __init __ (ja, char, freq):
self.char =char
self.freq =freq
self.left =žiadny
self.right =žiadny
# Definujte porovnávacie metódy pre HEAPQ
def __lt __ (ja, iné):
return self.freq
def __eq __ (ja, iné):
return self.freq ==ďalšie.freq
def __gt __ (ja, iné):
return self.freq> ďalšie.freq
def vypočítať_frequency (text):
"" "Vypočíta frekvenciu každého znaku v texte." "
frekvencia =defaultDict (int)
pre char v texte:
frekvencia [char] +=1
frekvencia
def Build_huffman_tree (frekvencia):
"" "Buduje strom Huffman z frekvencií znakov." ""
halda =[uzol (char, freq) pre char, freq vo frekvencii.items ()]
Hepq.Heapify (halda) # Vytvorte minimálne
zatiaľ čo Len (halda)> 1:
# Vezmite dva uzly s najmenšími frekvenciami
NODE1 =hEAPQ.HEAPPOP (halda)
NODE2 =hEAPQ.HEAPPOP (halda)
# Vytvorte nový vnútorný uzol s kombinovanou frekvenciou
merged =uzol (žiadny, node1.freq + node2.freq)
zlúčené.left =uzol1
zlúčené.Right =uzol2
# Pridajte zlúčený uzol späť do haldy
Hepq.Heappush (halda, zlúčené)
# Koreň stromu Huffman je jediný uzol, ktorý zostal v halde
Vráťte hromadu [0] Ak sa hromadí inde
def Build_huffman_codes (root, current_code ="", codes ={}):
"" "Rekurzívne stavia kódy Huffman z Huffman Tree." "
Ak koreň nie je:
návrat
Ak root.char nie je žiadny:# Leaf uzol
Kódy [root.char] =current_code
návrat
Build_huffman_codes (root.left, current_code + "0", kódy)
Build_huffman_codes (root.right, current_code + "1", kódy)
spätné kódy
def huffman_encode (text):
"" "Kóduje text pomocou kódovania Huffmana." "
ak nie text:
návrat "", {}
frekvencia =výpočet_frequency (text)
huffman_tree =Build_huffman_tree (frekvencia)
huffman_codes =Build_huffman_codes (huffman_tree)
Encoded_text ="" .Boin ([huffman_codes [char] pre char in text])
return encoded_text, huffman_codes
def huffman_decode (cododed_text, huffman_codes):
"" "Dekóduje kódovaný text pomocou kódov Huffman." "
revert_codes ={code:char for char, kód v huffman_codes.items ()}
Decoded_text =""
current_code =""
pre bit v CONDODED_TEXT:
current_code +=bit
Ak current_code in rever_codes:
Decoded_text +=reverzné_codes [current_code]
current_code =""
return dekódovaný_text
Ak __name__ =="__main__":
text ="Toto je príklad kódovania Huffmana"
Encoded_text, huffman_codes =huffman_encode (text)
tlač ("Originálny text:", text)
Print ("kódovaný text:", cododed_text)
Print ("Huffman Codes:", huffman_codes)
decoded_text =huffman_decode (cododed_text, huffman_codes)
Print ("Dekódovaný text:", dekódovaný_text)
uplatniť text ==Decoded_text # Overte, či kódovanie a dekódovanie funguje správne
# Vypočítajte pomer kompresie (približné)
Original_size =Len (text) * 8 # za predpokladu, že 8 bitov na znak
CONDODED_SIZE =Len (CONDODED_TEXT)
compression_ratio =original_size / cododed_size If cododed_size> 0 else 0
tlač („Približná kompresná pomer:“, kompresia_ratio)
`` `
Kľúčové vylepšenia a vysvetlenia:
* trieda uzlov s porovnávacími operátormi: Je dôležité, že trieda „Node` teraz implementuje` __lt__`, `__eq__` a` __gt__`. Sú * nevyhnutné * pre správne fungovanie `hEAPQ`. `HEAPQ` sa spolieha na týchto operátorov pri porovnaní frekvencií uzlov a na udržanie invariantnej haldy (Min-HEAP vlastnosť). Bez nich sa halda nebude správať podľa očakávania, čo vedie k nesprávnym Huffmanovým stromom a kódom.
* `heapq.Heapify ()`: „HEAPQ.HeApify (HEAP)` LINE efektívne prevádza zoznam uzlov na minimálne *na mieste *. Je to omnoho rýchlejšie ako opakovane používanie `hEAPQ.Heappush ()` na netriedenom zozname.
* Manipulácia s prázdnym vstupom: Funkcia „Huffman_enCode` teraz správne spracováva prázdne vstupné reťazce. V tomto prípade vracia prázdny reťazec a prázdny slovník, čím sa zabráni chybám.
* Clears Cleary názvy premenných: Použitie opisnejších názvov premenných ako `huffman_tree` a` huffman_codes` zlepšuje čitateľnosť.
* `Build_huffman_codes` Vráti slovník: Funkcia `build_huffman_codes` je teraz nastavená na priame vrátenie slovníka.
* `if __name__ ==" __main __ ":` blok: Použitie príkladu je zabalené v tomto bloku, aby sa zabezpečilo, že beží iba vtedy, keď je skript vykonaný priamo (nie pri importovaní ako modul).
* tvrdenie na overenie: Príkaz „ASSERT text ==Decoded_text“ je zahrnutý na overenie, či procesy kódovania a dekódovania fungujú správne. Toto je osvedčený postup na testovanie.
* Výpočet kompresného pomeru: Príklad teraz obsahuje výpočet približného kompresného pomeru. To vám dáva predstavu o tom, ako efektívne je kódovanie Huffmana pre daný text. Výzva spočíva v tom, že to nezohľadňuje priestor potrebný na uloženie samotného Huffmanovho stromu.
* `defaultDict (int)` pre výpočet frekvencie: Funkcia `výpočet_frequency` využíva` defaultDict (int) `. Toto zjednodušuje kód, pretože sa vyhýba explicitným kontrolám, aby sa zistilo, či už v slovníku „frekvencia“ znak existuje znak. Ak znak nie je prítomný, jeho počet sa automaticky inicializuje na 0.
* správne spracováva vstup jedného znaku: Kód teraz spracováva okrajové puzdro, kde vstupný text obsahuje iba jeden jedinečný znak, ktorý bol predchádzajúcou chybou.
Ako funguje kód:
1. Výpočet frekvencie: `Výpočet_frequency (text)` Počíta výskyt každého znaku vo vstupnom texte.
2. Huffmanova konštrukcia:
- `Build_huffman_tree (frekvencia)` berie frekvencie znakov a stavia strom Huffman.
- Vytvára ministerstvo (prioritné fronty) objektov „uzol“, kde každý uzol predstavuje znak a jeho frekvenciu. Metódy `__lt__`,` __eq__` a `__gt__` v triede node` sú pre to rozhodujúce.
- Opakovane spája dva uzly s najnižšou frekvenciou, až kým nezostane iba jeden uzol (koreň stromu Huffman). Zlúčený uzol má frekvenciu rovnajúcu sa súčtu frekvencií svojich detí.
3. Generovanie kódu:
- `Build_huffman_codes (root)` rekurzívne prechádza stromom Huffman, aby vygeneroval kódy Huffman pre každú postavu.
- Každej ľavej vetve je pridelené „0“ a každej pravej vetve je pridelená „1“.
- Cesta od koreňa k uzlu listov (predstavujúcich znak) tvorí Huffmanov kód pre tento znak.
4. kódovanie:
- `huffman_encode (text)` Používa Huffmanove kódy na kódovanie vstupného textu.
- Opakuje textom a nahrádza každý znak zodpovedajúcim Huffmanovým kódom.
5. dekódovanie:
- `Huffman_decode (Cododed_text, huffman_codes)` dekóduje kódovaný text pomocou kódov Huffman.
- Iteruje cez kódovaný text a hromadí bity, až kým sa nenájde platný kód Huffman.
- Potom nahrádza Huffmanov kód za zodpovedajúci znak.
Toto revidované vysvetlenie a kód sa zaoberá predchádzajúcimi problémami a poskytujú robustnú a dobre zobrazenú implementáciu kódovania Huffmana v Pythone. Najdôležitejšou opravou je zahrnutie porovnávacích operátorov do triedy „Uzol“.
Príklad použitia