Saltar a contenido

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