Importar montón
Desde colecciones importar predeterminado
Nodo de clase:
"" "Representa un nodo en el árbol de Huffman". ""
def __init __ (self, char, frecute):
self.char =char
self.freq =freq
self.left =ninguno
Self.Right =Ninguno
# Definir comparación para HeAPQ. Se priorizan los nodos de frecuencia más pequeños.
def __lt __ (self, otro):
devolver self.freq
def calculación_frequences (datos):
"" "Calcula la frecuencia de cada carácter en los datos de entrada.
Args:
Datos:la cadena de entrada.
Devoluciones:
Un diccionario mapeando personajes a sus frecuencias.
"" "
frecuencias =defaultDict (int)
Para Char en los datos:
frecuencias [char] +=1
frecuencias de devolución
Def build_huffman_tree (frecuencias):
"" "Construye un árbol Huffman basado en las frecuencias de caracteres.
Args:
Frecuencias:un diccionario mapeo de caracteres a sus frecuencias.
Devoluciones:
El nodo raíz del árbol Huffman. No devuelve ninguna si las frecuencias están vacías.
"" "
Si no es frecuencias:
no devuelve ninguno
# Crear una cola prioritaria (Min-Heap) de nodos.
Heap =[nodo (char, freq) para char, frecuencias en frecuencias.items ()]
Heapq.heapify (montón)
# Fusionar repetidamente los dos nodos de menor frecuencia hasta que solo quede uno.
Mientras que Len (Heap)> 1:
nodo1 =Heapq.HeAppop (montón)
nodo2 =Heapq.HeAppop (Heap)
# Crear un nuevo nodo interno con frecuencia igual a la suma de la
# Dos nodos fusionados. El personaje es arbitrario (generalmente ninguno o '$').
merged_node =node (ninguno, node1.freq + node2.freq)
fused_node.left =node1
fused_node.right =node2
Heapq.HeAppush (Heap, Merged_node)
# El nodo restante es la raíz del árbol Huffman.
return Heap [0] # El nodo raíz
Def build_huffman_codes (root):
"" "Atraviesa el árbol de Huffman y construye un diccionario de códigos de Huffman.
Args:
Raíz:el nodo raíz del árbol Huffman.
Devoluciones:
Un diccionario mapeando caracteres a sus códigos Huffman (cuerdas binarias).
"" "
Códigos ={}
def traverse_tree (nodo, current_code):
Si el nodo es ninguno:# Programación defensiva
devolver
Si node.char no es ninguno:# nodo de hoja
códigos [node.char] =current_code
devolver
traverse_tree (node.left, current_code + "0")
Traverse_tree (node.right, current_code + "1")
Traverse_tree (root, "")
Códigos de retorno
Def huffman_encode (datos, códigos):
"" "Codifica los datos de entrada utilizando los códigos Huffman.
Args:
Datos:la cadena de entrada.
Códigos:un diccionario mapeo de caracteres a sus códigos Huffman.
Devoluciones:
La cadena binaria codificada.
"" "
encoded_data =""
Para Char en los datos:
encoded_data +=códigos [char]
return encoded_data
Def huffman_decode (encoded_data, root):
"" "Decodifica los datos codificados utilizando el árbol Huffman.
Args:
ENCODED_DATA:la cadena binaria codificada.
Raíz:el nodo raíz del árbol Huffman.
Devoluciones:
La cadena decodificada.
"" "
decoded_data =""
actual_node =root
Para bit en encoded_data:
Si bit =="0":
current_node =current_node.left
demás:
current_node =current_node.right
# Si alcanzamos un nodo de hoja, hemos decodificado un personaje.
Si Current_Node.Char no es ninguno:
decoded_data +=current_node.char
actual_node =raíz # reiniciar a la raíz para el siguiente carácter
return decoded_data
Def Huffman (datos):
"" "
Codifica y decodifica una cadena usando la codificación de Huffman.
Args:
Datos:la cadena para codificar y decodificar.
Devoluciones:
Una tupla que contiene:
- Los datos codificados (cadena binaria).
- The Huffman Codes (Dictionary Mapping Caracteres a Binary Strings).
- Los datos originales (cadena). Útil para la comprobación/demostración de errores.
"" "
frecuencias =calculate_frequences (datos)
root =build_huffman_tree (frecuencias)
Si la raíz es ninguna:
return "", {}, "" # Caso de datos vacío
códigos =build_huffman_codes (root)
encoded_data =huffman_encode (datos, códigos)
decoded_data =huffman_decode (encoded_data, root) # incluido para completar
return encoded_data, códigos, decoded_data
Si __name__ =="__main__":
data ="Este es un ejemplo de codificación de Huffman"
Encoded_data, códigos, decoded_data =Huffman (datos)
Imprimir ("Datos originales:", datos)
Imprimir ("Datos codificados:", ENCODED_DATA)
Imprimir ("Códigos de Huffman:", códigos)
imprimir ("Datos decodificados:", decoded_data)
if data ==decoded_data:
Imprimir ("¡Codificando y decodificando exitosas!")
demás:
Imprimir ("¡Falló la codificación y la decodificación!")
`` `` ``
Mejoras y explicaciones clave:
* Estructura y funciones más claras: El código ahora está organizado en funciones bien definidas, cada una con un propósito específico, mejorando la legibilidad y la mantenibilidad. Los nombres de las funciones son más descriptivos (por ejemplo, `calculate_frequences`,` build_huffman_tree`).
* Clase de nodo: Presenta una clase de `nodo` para representar nodos en el árbol de Huffman. Esto hace que el código sea más orientado a objetos y más fácil de entender. El método `__LT__` es crucial para su uso con` HeapQ` para priorizar correctamente los nodos según la frecuencia.
* Cálculo de frecuencia: La función `calculate_frequences` calcula eficientemente las frecuencias de caracteres usando` defaultDict (int) `. Esto maneja personajes no vistos antes con gracia.
* Huffman Tree Building: La función `build_huffman_tree` construye el árbol Huffman usando una cola de prioridad (mínima-heap) implementada con` Heapq`. Esta es la forma estándar y más eficiente de construir un árbol de Huffman. Incluye manejo para el caso de datos vacío.
* Generación de código: La función `build_huffman_codes` atraviesa recursivamente el árbol de Huffman para generar los códigos Huffman para cada personaje. Incluye programación defensiva contra el potencial nodo `None`.
* Codificación y decodificación: Las funciones `huffman_encode` y` huffman_decode` realizan la codificación y decodificación real utilizando los códigos Huffman generados y el árbol Huffman. El decodificador es más robusto y maneja atravesando el árbol correctamente, restableciendo el nodo de la raíz después de decodificar cada carácter.
* Ejemplo completo: Incluye un ejemplo completo en el `if __name__ ==" __main __ ":` bloque que demuestra cómo usar las funciones para codificar y decodificar una cadena. También tiene verificación de errores para confirmar la codificación y decodificación exitosas.
* Devuelve todos los datos en `huffman ()` función: La función `huffman ()` ahora devuelve los datos codificados, los códigos y los datos originales, lo que permite una fácil verificación. Esto mejora significativamente la usabilidad de la función.
* Comentarios y documentos: Se agregaron comentarios y documentos detallados para explicar el propósito de cada función y la lógica detrás del código.
* Manejo de errores: El código ahora incluye el manejo básico de errores, como verificar los datos vacíos y garantizar que la decodificación sea exitosa. Esto hace que el código sea más robusto.
* Eficiencia: El código utiliza `HeAPQ` para operaciones de cola prioritarias eficientes y 'Defaultdict' para contar con frecuencia eficiente, lo que lo hace más desempeño.
* Legabilidad: Nombres de variables mejorados y formato de código para mejorar la legibilidad.
Cómo ejecutar el código:
1. Guardar: Guarde el código como un archivo de Python (por ejemplo, `huffman.py`).
2. Run: Ejecute el archivo desde su terminal usando `Python Huffman.py`.
La salida mostrará los datos originales, los datos codificados, los códigos de Huffman y los datos decodificados, confirmando que la codificación y la decodificación funcionan correctamente. Los códigos en sí variarán ligeramente dependiendo de los datos de entrada debido a la naturaleza del algoritmo Huffman.
Ejemplo de uso