Levenshtein Coding
1. Definición
Levenshtein coding es un método de codificación que representa números enteros no negativos mediante la longitud de sus representaciones binarias, seguida de la cantidad de veces que se requiere aplicar la función piso del logaritmo en base 2 sobre dicho número. En este proceso, un entero igual a cero se codifica como un solo bit "0", mientras que los demás números se descomponen en sus dígitos binarios y se codifican mediante una secuencia de bits que indica la cantidad de "1" consecutivos, seguida por la representación binaria de dichos dígitos. Este enfoque busca aprovechar la redundancia de los dígitos menos significativos, reduciendo así la longitud promedio de la codificación y optimizando la representación de números con una alta concentración de ceros en sus partes menos significativas.
2. Implementación
Encoding
// Función para codificar utilizando el algoritmo de Levenshtein
void levenshteinEncode(char* source, char* dest) {
IntReader intreader(source);
BitWriter bitwriter(dest);
// Mientras haya enteros por leer en la cadena de entrada
while (intreader.hasLeft()) {
int num = intreader.getInt();
// Si el entero es cero, se codifica con un solo bit "0"
if (num == 0) {
bitwriter.outputBit(0);
} else {
int c = 0;
BitStack bits;
// Ciclo para calcular y codificar los bits del número
do {
int m = 0;
// Calcular floor(log2(num))
for (int temp = num; temp > 1; temp >>= 1)
++m;
// Almacenar los bits del número en la pila
for (int i = 0; i < m; ++i)
bits.pushBit((num >> i) & 1);
num = m;
++c;
} while (num > 0);
// Escribir la cantidad de "1"s seguidos de un "0"
for (int i = 0; i < c; ++i)
bitwriter.outputBit(1);
bitwriter.outputBit(0);
// Escribir los bits almacenados en la pila
while (bits.length() > 0)
bitwriter.outputBit(bits.popBit());
}
}
}
Decoding
// Función para decodificar utilizando el algoritmo de Levenshtein
void levenshteinDecode(char* source, char* dest) {
BitReader bitreader(source);
IntWriter intwriter(dest);
// Mientras haya bits por leer en la cadena de entrada
while (bitreader.hasLeft()) {
int n = 0;
// Contar la cantidad de bits "1" consecutivos
while (bitreader.inputBit()) {
++n;
}
int num;
// Si la cantidad de bits "1" es cero, el número es cero
if (n == 0) {
num = 0;
} else {
num = 1;
// Ciclo para decodificar el número
for (int i = 0; i < n - 1; ++i) {
int val = 1;
// Leer y construir el valor en binario
for (int j = 0; j < num; ++j) {
val = (val << 1) | bitreader.inputBit();
}
num = val;
}
}
// Escribir el valor decodificado
intwriter.putInt(num);
}
// Cerrar los flujos de bits y enteros
bitreader.close();
intwriter.close();
}
3. Casos de uso
Esta codificación se utiliza en diversas aplicaciones en las que se busca representar eficientemente números enteros no negativos. Entre ellos:
- Compresión de datos
- Algoritmos de búsqueda
- Sistemas de almacenamiento eficiente
- Representación de datos en redes
- Procesamiento de imágenes y señales
- Optimización de algoritmos genéticos
- Representación de índices en bases de datos
Referencias
- https://en.wikipedia.org/wiki/Levenshtein_coding