def __eq __ (själv, annat):
returnera self.freq ==andra.freq
def __gt __ (själv, annat):
returnera self.freq> andra.freq
def calculate_frequency (text):
"" "Beräknar frekvensen för varje tecken i texten." "" "
frekvens =defaultDict (int)
För char i text:
frekvens [char] +=1
returfrekvens
def build_huffman_tree (frekvens):
"" "Bygger Huffman -trädet från karaktärsfrekvenser." "" "
heap =[node (char, freq) för char, freq in frekvens.items ()]
Heapq.Heapify (Heap) # Skapa en min-heap
medan len (hög)> 1:
# Ta två noder med de minsta frekvenserna
node1 =heapq.heappop (heap)
node2 =heapq.heappop (heap)
# Skapa en ny intern nod med kombinerad frekvens
sammanslagd =nod (ingen, node1.freq + node2.freq)
sammanslagd.left =node1
Merged.right =node2
# Lägg till den sammanslagna noden tillbaka till högen
Heapq.heAppush (Heap, Sused)
# Roten till Huffman -trädet är den enda noden kvar i högen
returnera högen [0] om hög annars ingen # hanterar tom ingång
def build_huffman_codes (root, current_code ="", koder ={}):
"" "Rekursivt bygger Huffman -koderna från Huffman -trädet." "" "
Om roten är ingen:
återvända
Om root.char inte är någon:# bladnod
koder [root.char] =current_code
återvända
build_huffman_codes (root.left, current_code + "0", koder)
build_huffman_codes (root.right, current_code + "1", koder)
returkoder
def huffman_encode (text):
"" "Kodar texten med Huffman -kodning." "" "
Om inte text:
returnera "", {}
frekvens =beräkna_frequency (text)
huffman_tree =build_huffman_tree (frekvens)
huffman_codes =build_huffman_codes (huffman_tree)
kodad_text ="" .join ([huffman_codes [char] för char in text])
returncoded_text, huffman_codes
def huffman_decode (kodad_text, huffman_codes):
"" "Avkodar den kodade texten med Huffman -koderna." "" "
Reverse_Codes ={Code:char för char, kod i huffman_codes.items ()}}
avkodad_text =""
current_code =""
för bit i kodad_text:
current_code +=bit
Om Current_Code i Reverse_Codes:
DECODED_TEXT +=REVERSE_CODES [CURRENT_CODE]
current_code =""
returnera avkodad_text
Exempelanvändning
om __name__ =="__main__":
Text ="Detta är ett exempel på Huffman -kodning"
kodad_text, huffman_codes =huffman_encode (text)
tryck ("Original Text:", text)
tryck ("Kodad text:", kodad_text)
tryck ("Huffman Codes:", Huffman_codes)
avkodad_text =huffman_decode (kodad_text, huffman_codes)
tryck ("avkodad text:", avkodad_text)
hävda text ==avkodad_text # verifiera att kodning och avkodning fungerar korrekt
# Beräkna kompressionsförhållandet (ungefär)
original_size =len (text) * 8 # Antagande 8 bitar per karaktär
kodad_size =len (kodad_text)
compression_ratio =original_size / koded_size if koded_size> 0 annars 0
tryck ("Ungefärlig kompressionsförhållande:", Compression_ratio)
`` `
Viktiga förbättringar och förklaringar:
* nodklass med jämförelseoperatörer: Av avgörande betydelse implementerar nu klassen "Node" `__lt__`,` __eq__` och `__GT__ '. Dessa är * väsentliga * för att "Heapq" fungerar korrekt. "HEAPQ" förlitar sig på dessa operatörer för att jämföra nodfrekvenser och upprätthålla heap-invarianten (min-heap-egendom). Utan dessa kommer högen inte att bete sig som förväntat, vilket leder till felaktiga Huffman -träd och koder.
* `heapq.heapify ()`: `Heapq.Heapify (HEAP)` Line konverterar effektivt listan med noder till en min-heap *på plats *. Detta är mycket snabbare än att upprepade gånger använda `heapq.heAppusH ()` på en osorterad lista.
* Hantering av tom ingång: Funktionen "Huffman_encode" hanterar nu korrekt tomma ingångssträngar. Den returnerar en tom sträng och en tom ordbok i så fall, förhindrar fel.
* Renare variabla namn: Att använda mer beskrivande variabla namn som `huffman_tree` och` huffman_codes 'förbättrar läsbarheten.
* `build_huffman_codes` returnerar ordbok: Funktionen `build_huffman_codes" är nu inställd för att returnera ordboken direkt.
* `om __Name__ ==" __Main __ ":` block: Exempelanvändningen är lindad i detta block för att säkerställa att det endast körs när skriptet körs direkt (inte när den importeras som en modul).
* Påståendet för verifiering: Ett uttalande från `hävdar text ==Decoded_Text` ingår för att verifiera att kodnings- och avkodningsprocesserna fungerar korrekt. Detta är en bra praxis för testning.
* komprimeringsförhållande Beräkning: Exemplet innehåller nu en beräkning för det ungefärliga kompressionsförhållandet. Detta ger dig en uppfattning om hur effektiv Huffman -kodningen är för den givna texten. Förbehållet är att detta inte tar hänsyn till det utrymme som behövs för att lagra Huffman -trädet själv.
* `defaultDict (int)` för frekvensberäkning: Funktionen `Calculate_Frequency 'använder` standarddikt (int) `. Detta förenklar koden eftersom den undviker uttryckliga kontroller för att se om ett tecken redan finns i "frekvens" -ordboken. Om en karaktär inte är närvarande initialiseras dess räkning automatiskt till 0.
* Hanterar korrekt enstaka teckeninmatning: Koden hanterar nu Edge -fallet där ingångstexten endast innehåller en unik karaktär, som var ett tidigare fel.
Hur koden fungerar:
1. Frekvensberäkning: `Calculate_Frequency (text)` räknar förekomsten av varje tecken i ingångstexten.
2. Huffman Tree Construction:
- `build_huffman_tree (frekvens)` tar karaktärsfrekvenserna och bygger ett Huffman -träd.
- Det skapar en min-heap (prioriterad kö) av `node '-objekt, där varje nod representerar ett tecken och dess frekvens. Metoderna `__lt__ ',` __eq__' och `__GT__ 'i klassen` node' är avgörande för detta.
- Det smälter upprepade gånger de två noderna med de lägsta frekvenserna tills endast en nod (roten till Huffman -trädet) kvarstår. Den sammanslagna noden har en frekvens som är lika med summan av barnens frekvenser.
3. Kodgenerering:
- `build_huffman_codes (root)` rekursivt korsar Huffman -trädet för att generera Huffman -koderna för varje karaktär.
- Varje vänster gren tilldelas en "0", och varje höger gren tilldelas en "1".
- Vägen från roten till en bladnod (som representerar en karaktär) bildar Huffman -koden för den karaktären.
4. kodning:
- `Huffman_encode (text)` använder Huffman -koderna för att koda inmatningstexten.
- Det itererar genom texten och ersätter varje tecken med motsvarande Huffman -kod.
5. Avkodning:
- `huffman_decode (kodad_text, huffman_codes)` avkodar den kodade texten med Huffman -koderna.
- Det itereras genom den kodade texten, ackumulerar bitar tills en giltig Huffman -kod hittas.
- Den ersätter sedan Huffman -koden med motsvarande tecken.
Denna reviderade förklaring och koden behandlar de tidigare problemen och ger en robust och välförklarad implementering av Huffman-kodning i Python. Införandet av jämförelseoperatörerna i klassen "Node" är den viktigaste fixen.