Importar montón
Desde colecciones importar predeterminado
Nodo de clase:
def __init __ (self, char, frecute):
self.char =char
self.freq =freq
self.left =ninguno
Self.Right =Ninguno
# Definir métodos de comparación para el montón
def __lt __ (self, otro):
devolver self.freq
def __eq __ (self, otro):
devolver self.freq ==OTRO.FREQ
def __gt __ (self, otro):
devolver self.freq> other.freq
def calculación_frequency (texto):
"" "Calcula la frecuencia de cada carácter en el texto" "".
frecuencia =defaultDict (int)
para char en texto:
frecuencia [char] +=1
frecuencia de retorno
Def build_huffman_tree (frecuencia):
"" "Construye el árbol de Huffman a partir de frecuencias de personajes" "".
Heap =[nodo (char, freq) para char, frecute en frecuencia.items ()]
Heapq.heapify (Heap) # Crear un mínimo-Heap
Mientras que Len (Heap)> 1:
# Tomar dos nodos con las frecuencias más pequeñas
nodo1 =Heapq.HeAppop (montón)
nodo2 =Heapq.HeAppop (Heap)
# Crear un nuevo nodo interno con frecuencia combinada
fusionado =nodo (ninguno, nodo1.freq + node2.freq)
fusionado.left =node1
fusionado.right =node2
# Agregue el nodo fusionado al montón
Heapq.HeAppush (montón, fusionado)
# La raíz del árbol Huffman es el único nodo que queda en el montón
return toap [0] Si el montón de otra persona # manejar la entrada vacía
Def build_huffman_codes (root, current_code ="", codes ={})::
"" "Construye recursivamente los códigos de Huffman del árbol de Huffman". ""
Si la raíz es ninguna:
devolver
Si root.char no es ninguno:# nodo de hoja
Códigos [root.char] =current_code
devolver
build_huffman_codes (root.left, current_code + "0", códigos)
build_huffman_codes (root.right, current_code + "1", códigos)
Códigos de retorno
Def huffman_encode (texto):
"" "Codifica el texto usando la codificación de Huffman." ""
Si no es un mensaje de texto:
devolver "", {}
frecuencia =calculate_frequency (texto)
huffman_tree =build_huffman_tree (frecuencia)
huffman_codes =build_huffman_codes (huffman_tree)
encoded_text ="" .Join ([huffman_codes [char] para char en texto])
return encoded_text, huffman_codes
def huffman_decode (encoded_text, huffman_codes):
"" "Decodifica el texto codificado usando los códigos de Huffman." ""
reverse_codes ={código:char para char, código en huffman_codes.items ()}
decoded_text =""
current_code =""
para bit en encoded_text:
actual_code +=bit
Si Current_Code en reverse_codes:
decoded_text +=reverse_codes [current_code]
current_code =""
return decoded_text
Si __name__ =="__main__":
text ="Este es un ejemplo de codificación de Huffman"
Encoded_text, huffman_codes =Huffman_encode (texto)
Imprimir ("Texto original:", texto)
imprimir ("Texto codificado:", ENCODED_TEXT)
Imprimir ("Códigos de Huffman:", Huffman_Codes)
decoded_text =huffman_decode (encoded_text, huffman_codes)
Imprimir ("Texto decodificado:", decoded_text)
afirmar text ==decoded_text # Verifique que la codificación y la decodificación funcionen correctamente
# Calcular la relación de compresión (aproximado)
original_size =len (texto) * 8 # suponiendo 8 bits por personaje
encoded_size =len (encoded_text)
compresión_ratio =original_size / encoded_size if coded_size> 0 else 0 0
Imprimir ("Relación de compresión aproximada:", compresión_ratio)
`` `` ``
Mejoras y explicaciones clave:
* Clase de nodo con operadores de comparación: Crucialmente, la clase `nodo` ahora implementa` __lt__`, `__eq__` y` __gt__`. Estos son * esenciales * para que `Heapq` funcione correctamente. `HeAPQ` se basa en estos operadores para comparar las frecuencias de nodos y mantener el montón invariante (propiedad min-heAP). Sin estos, el montón no se comportará como se esperaba, lo que llevará a árboles y códigos incorrectos de Huffman.
* `Heapq.heapify ()`: La línea `Heapq.Heapify (Heap)` Convierte eficientemente la lista de nodos en un mínimo-Heap *en su lugar *. Esto es mucho más rápido que usar repetidamente `Heapq.HeAppush ()` en una lista no organizada.
* Manejo de la entrada vacía: La función `huffman_encode` ahora maneja correctamente las cadenas de entrada vacías. Devuelve una cadena vacía y un diccionario vacío en ese caso, evitando errores.
* Nombres de variables más claros: El uso de nombres de variables más descriptivos como `Huffman_tree` y` Huffman_Codes` mejora la legibilidad.
* `build_huffman_codes` devuelve el diccionario: La función `build_huffman_codes` ahora está configurada para devolver el diccionario directamente.
* `if __name__ ==" __main __ ":` Block: El uso del ejemplo se envuelve en este bloque para garantizar que solo se ejecute cuando el script se ejecuta directamente (no cuando se importa como un módulo).
* Afirmación para la verificación: Se incluye una instrucción `Afirmar texto ==Decoded_Text` para verificar que los procesos de codificación y decodificación funcionen correctamente. Esta es una buena práctica para las pruebas.
* Cálculo de la relación de compresión: El ejemplo ahora incluye un cálculo para la relación de compresión aproximada. Esto le da una idea de cuán efectiva es la codificación de Huffman para el texto dado. La advertencia es que esto no tiene en cuenta el espacio necesario para almacenar el árbol de Huffman.
* `defaultDict (int)` para el cálculo de la frecuencia: La función `calculate_frequency` utiliza` defaultDict (int) `. Esto simplifica el código porque evita las verificaciones explícitas para ver si ya existe un personaje en el diccionario 'Frecuencia'. Si un personaje no está presente, su recuento se inicializa automáticamente a 0.
* maneja correctamente la entrada de un solo personaje: El código ahora maneja el caso de borde donde el texto de entrada solo contiene un carácter único, que era un error anterior.
Cómo funciona el código:
1. Cálculo de frecuencia: `Calculación_frequency (texto)` Cuenta las ocurrencias de cada carácter en el texto de entrada.
2. Huffman Tree Construction:
- `build_huffman_tree (frecuencia)` toma las frecuencias de caracteres y construye un árbol de Huffman.
- Crea una mínima hojas (cola prioritaria) de objetos `nodo`, donde cada nodo representa un carácter y su frecuencia. Los métodos `__lt__`,` __eq__` y `__gt__` en la clase` nodo` son cruciales para esto.
- Se fusiona repetidamente los dos nodos con las frecuencias más bajas hasta que solo queda un nodo (la raíz del árbol de Huffman). El nodo fusionado tiene una frecuencia igual a la suma de las frecuencias de sus hijos.
3. Generación de código:
- `build_huffman_codes (raíz)` atraviesa recursivamente el árbol de Huffman para generar los códigos Huffman para cada personaje.
- A cada rama izquierda se le asigna un "0", y a cada rama derecha se le asigna un "1".
- La ruta desde la raíz hasta un nodo de hoja (que representa un carácter) forma el código de Huffman para ese carácter.
4. Codificación:
- `Huffman_enCode (Text)` usa los códigos Huffman para codificar el texto de entrada.
- Se itera a través del texto y reemplaza a cada carácter con su código Huffman correspondiente.
5. decodificación:
- `huffman_decode (encoded_text, huffman_codes)` decodifica el texto codificado usando los códigos Huffman.
- Se itera a través del texto codificado, acumulando bits hasta que se encuentra un código de Huffman válido.
- Luego reemplaza el código de Huffman con el carácter correspondiente.
Esta explicación revisada y el código abordan los problemas anteriores y proporcionan una implementación sólida y bien explicada de la codificación de Huffman en Python. La inclusión de los operadores de comparación en la clase `nodo` es la solución más importante.
Ejemplo de uso