Programación en C - Codificar texto con matriz de 25 letras

C – Codificación de texto con matriz

Hoy te mostraré un ejercicio resuelto en el lenguaje de programación C. Se trata de codificar un texto usando una matriz de 5 x 5 en donde una letra del alfabeto (que es el código) se remueve de la matriz para que solo haya 25 letras.

No encontré un nombre para esta codificación, pero básicamente se trata de eso: solicitar la letra que será el código, generar la matriz con las 25 letras sin contar el código y luego cifrar letras de par en par.

A continuación te muestro los detalles del ejercicio.

Descripción del ejercicio

Una simple y efectiva forma de codificar textos consiste en ubicar 25 de las 26 letras del alfabeto inglés en una matriz de 5×5. El nombre del código lo determina la letra faltante en la matriz, como es el caso del código “K” cuya representación es la siguiente:

|  |   |   |   |   |
| ------------- | ------------- | ------------- | ------------- | ------------- |
| A | B | C | D | E |
| F | G | H | I | J |
| L | M | N | O | P |
| Q | R | S | T | U |
| V | W | X | Y | Z |

Cada palabra del texto se considera compuesta de pares de letras. Si el número de letras en una palabra es impar, la última letra se conserva. También se conserva la letra que le da el nombre al código.

Un par de letras se codifica reemplazando la primera por aquella ubicada en su misma fila pero en la columna de la segunda y, la segunda por aquella ubicada en su misma fila pero en la columna de la primera.

Por ejemplo, usando el código “K”, si el texto original es COMPUTADOR CUANTICO el respectivo texto codificado es DNPMTUDAMT ESCLTIDN.

Especificación

Respecto de esta forma de codificación, considérese un texto compuesto de palabras escritas con letras mayúsculas, separadas por un carácter blanco y finalizado con un “*”, para desarrollar en lenguaje de programación C una aplicación que cumpla con lo que a continuación se indica:

  • Declaración: declara las estructuras de datos necesarias
  • leeCodigo: Lee un código (letra) y genera la correspondiente matriz
  • leeTexto: Lee un texto y lo almacena en un arreglo
  • codifica: Genera un arreglo con el texto codificado, habiendo recibido la matriz y el arreglo con el texto original.
  • decodifica: Genera un arreglo con el texto decodificado, habiendo recibido la matriz y el arreglo con el texto codificado.
  • muestraMatriz: Despliega la matriz
  • muestraTexto: despliega el texto (original o codificado) contenido en un arreglo
  • main: Llama organizadamente a las funciones anteriores.

Solución al ejercicio

Lo más confuso del ejercicio es hacer la codificación de cada par de letras, pero con las funciones adecuadas y aisladas podemos lograrlo. Veamos las funciones en orden.

La función que imprime la matriz es la siguiente. Simplemente hace 2 ciclos for, pues es un arreglo bidimensional:

void muestraMatriz(char matriz[LONGITUD][LONGITUD])
{
    int y;
    for (y = 0; y < LONGITUD; y++)
    {
        int x;
        for (x = 0; x < LONGITUD; x++)
        {
            char actual = matriz[y][x];
            printf("| %c ", actual);
        }
        printf("|\n");
    }
}

Luego tenemos a la función que lee el código y genera la matriz. En este caso almacenamos el código de manera global, pues vamos a usarlo más tarde en otras funciones.

Para esto de la matriz y las letras usamos el aumento de caracteres o char, que en este caso permite aumentar una letra de modo que ‘A’ + 1 es ‘B’.

void leeCodigo(char matriz[LONGITUD][LONGITUD])
{
    printf("Ingresa el codigo: ");
    scanf("%c", &codigoGlobal);
    char letra = 'A';
    int y = 0, x = 0;
    while (letra <= 'Z')
    {
        if (letra == codigoGlobal)
        {
            letra++;
        }

        // Comprobación extra para cuando el código es 'Z'
        if (letra <= 'Z')
        {
            matriz[y][x] = letra;
        }
        x++;
        letra++;
        if (x >= LONGITUD)
        {
            x = 0;
            y++;
        }
        if (y >= LONGITUD)
        {
            y = 0;
        }
    }
}

También es necesario contar con funciones que nos digan la fila y la columna de las letras, pues recuerda que la codificación se trata de intercambiar letras buscando columnas y filas de la otra letra.

He repetido un poco el código, así que las funciones se parecen mucho:

int buscarFila(char matriz[LONGITUD][LONGITUD], char busqueda)
{
    int y;
    for (y = 0; y < LONGITUD; y++)
    {
        int x;
        for (x = 0; x < LONGITUD; x++)
        {
            char actual = matriz[y][x];
            if (actual == busqueda)
            {
                return y;
            }
        }
    }
    return -1;
}

int buscarColumna(char matriz[LONGITUD][LONGITUD], char busqueda)
{
    int y;
    for (y = 0; y < LONGITUD; y++)
    {
        int x;
        for (x = 0; x < LONGITUD; x++)
        {
            char actual = matriz[y][x];
            if (actual == busqueda)
            {
                return x;
            }
        }
    }
    return -1;
}

Estas funciones nos van a servir al remplazar las letras, y hablando de esa operación, tenemos las siguientes funciones que a partir del par de letras te indica el remplazo de la primera o de la segunda:

char remplazoPrimera(char matriz[LONGITUD][LONGITUD], char primeraLetra, char segundaLetra)
{
    int columnaPrimera = buscarColumna(matriz, primeraLetra);
    int filaPrimera = buscarFila(matriz, primeraLetra);
    int columnaSegunda = buscarColumna(matriz, segundaLetra);
    int filaSegunda = buscarFila(matriz, segundaLetra);
    char remplazoPrimera = matriz[filaPrimera][columnaSegunda];
    return remplazoPrimera;
}

char remplazoSegunda(char matriz[LONGITUD][LONGITUD], char primeraLetra, char segundaLetra)
{
    int columnaPrimera = buscarColumna(matriz, primeraLetra);
    int filaPrimera = buscarFila(matriz, primeraLetra);
    int columnaSegunda = buscarColumna(matriz, segundaLetra);
    int filaSegunda = buscarFila(matriz, segundaLetra);
    char remplazoSegunda = matriz[filaSegunda][columnaPrimera];
    return remplazoSegunda;
}

Finalmente tenemos a la función que codifica y decodifica. Básicamente son la misma función, pues lo que cambia es el texto, ya que si se codifica algo codificado el resultado es el texto original.

void codifica(char texto[MAXIMA_LONGITUD_CADENA], char matriz[LONGITUD][LONGITUD])
{
    int longitud = longitudCadena(texto);
    int x = 0;
    while (x < longitud)
    {
        char primera = texto[x];
        if (x + 1 < longitud)
        {
            char segunda = texto[x + 1];
            if (primera != ' ' && segunda != ' ' && primera != codigoGlobal && segunda != codigoGlobal)
            {
                char nuevaPrimera = remplazoPrimera(matriz, primera, segunda);
                char nuevaSegunda = remplazoSegunda(matriz, primera, segunda);
                texto[x] = nuevaPrimera;
                texto[x + 1] = nuevaSegunda;
                x++;
            }
        }
        x++;
    }
}

void decodifica(char texto[MAXIMA_LONGITUD_CADENA], char matriz[LONGITUD][LONGITUD])
{
    // Se usa la misma función
    codifica(texto, matriz);
}

Por cierto es importante notar que estas funciones no regresan nada, sino que modifican al texto que se les pasa como argumento. Ahora solo falta aplicar todas estas funciones en el main:

int main()
{
    char matriz[LONGITUD][LONGITUD];
    leeCodigo(matriz);
    printf("Matriz generada: \n");
    muestraMatriz(matriz);
    char texto[MAXIMA_LONGITUD_CADENA] = "";
    char textoCodificado[MAXIMA_LONGITUD_CADENA] = "";
    char textoDecodificado[MAXIMA_LONGITUD_CADENA] = "";
    int eleccion;
    printf("1. Codificar\n2. Decodificar\nElige [1-2]: ");
    scanf("%d", &eleccion);
    if (eleccion == 1)
    {
        printf("Voy a codificar un texto. Recuerda terminarlo con un *\n");
        leeTexto(texto);
        // Copiar el texto dentro del codificado para no modificar el original
        strcpy(textoCodificado, texto);
        // Codificarlo
        codifica(textoCodificado, matriz);
        printf("Texto codificado: \n");
        muestraTexto(textoCodificado);
    }
    else
    {
        printf("Voy a decodificar un texto. Recuerda terminarlo con un *\n");
        leeTexto(texto);
        // Copiar el texto dentro del decodificado para no modificar el original
        strcpy(textoDecodificado, texto);
        // Codificarlo
        decodifica(textoDecodificado, matriz);
        printf("Texto decodificado: \n");
        muestraTexto(textoDecodificado);
    }
}

Los comentarios dan una explicación adicional al código.

Poniendo todo junto

Programación en C - Codificar texto con matriz de 25 letras
Programación en C – Codificar texto con matriz de 25 letras

El código completo queda como se ve a continuación. Recuerda que tú puedes modificarlo como prefieras y adaptarlo a tus necesidades:

/*
  ____          _____               _ _           _       
 |  _ \        |  __ \             (_) |         | |      
 | |_) |_   _  | |__) |_ _ _ __ _____| |__  _   _| |_ ___ 
 |  _ <| | | | |  ___/ _` | '__|_  / | '_ \| | | | __/ _ \
 | |_) | |_| | | |  | (_| | |   / /| | |_) | |_| | ||  __/
 |____/ \__, | |_|   \__,_|_|  /___|_|_.__/ \__, |\__\___|
         __/ |                               __/ |        
        |___/                               |___/         
    
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me               /
 ------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
Creado por Parzibyte (https://parzibyte.me).
------------------------------------------------------------------------------------------------
            | IMPORTANTE |
Si vas a borrar este encabezado, considera:
Seguirme: https://parzibyte.me/blog/sigueme/
Y compartir mi blog con tus amigos
También tengo canal de YouTube: https://www.youtube.com/channel/UCroP4BTWjfM0CkGB6AFUoBg?sub_confirmation=1
Twitter: https://twitter.com/parzibyte
Facebook: https://facebook.com/parzibyte.fanpage
Instagram: https://instagram.com/parzibyte
Hacer una donación vía PayPal: https://paypal.me/LuisCabreraBenito
------------------------------------------------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#define LONGITUD 5                  // Longitud de la matriz
#define MAXIMA_LONGITUD_CADENA 1000 // Límite de cadenas
char codigoGlobal = ' ';
/*
    Prototipos de funciones
*/

void leeCodigo(char matriz[LONGITUD][LONGITUD]);
void leeTexto(char destino[MAXIMA_LONGITUD_CADENA]);
void codifica(char texto[MAXIMA_LONGITUD_CADENA], char matriz[LONGITUD][LONGITUD]);
void decodifica(char texto[MAXIMA_LONGITUD_CADENA], char matriz[LONGITUD][LONGITUD]);
void muestraMatriz(char matriz[LONGITUD][LONGITUD]);
void muestraTexto(char texto[MAXIMA_LONGITUD_CADENA]);
// Ayudantes:
int longitudCadena(char cadena[MAXIMA_LONGITUD_CADENA]);
int buscarFila(char matriz[LONGITUD][LONGITUD], char busqueda);
int buscarColumna(char matriz[LONGITUD][LONGITUD], char busqueda);
char remplazoPrimera(char matriz[LONGITUD][LONGITUD], char primeraLetra, char segundaLetra);
char remplazoSegunda(char matriz[LONGITUD][LONGITUD], char primeraLetra, char segundaLetra);
void consumirNuevaLinea(void);

int main()
{
    char matriz[LONGITUD][LONGITUD];
    leeCodigo(matriz);
    printf("Matriz generada: \n");
    muestraMatriz(matriz);
    char texto[MAXIMA_LONGITUD_CADENA] = "";
    char textoCodificado[MAXIMA_LONGITUD_CADENA] = "";
    char textoDecodificado[MAXIMA_LONGITUD_CADENA] = "";
    int eleccion;
    printf("1. Codificar\n2. Decodificar\nElige [1-2]: ");
    scanf("%d", &eleccion);
    if (eleccion == 1)
    {
        printf("Voy a codificar un texto. Recuerda terminarlo con un *\n");
        leeTexto(texto);
        // Copiar el texto dentro del codificado para no modificar el original
        strcpy(textoCodificado, texto);
        // Codificarlo
        codifica(textoCodificado, matriz);
        printf("Texto codificado: \n");
        muestraTexto(textoCodificado);
    }
    else
    {
        printf("Voy a decodificar un texto. Recuerda terminarlo con un *\n");
        leeTexto(texto);
        // Copiar el texto dentro del decodificado para no modificar el original
        strcpy(textoDecodificado, texto);
        // Codificarlo
        decodifica(textoDecodificado, matriz);
        printf("Texto decodificado: \n");
        muestraTexto(textoDecodificado);
    }
}

int longitudCadena(char cadena[MAXIMA_LONGITUD_CADENA])
{
    return strlen(cadena);
}
void muestraMatriz(char matriz[LONGITUD][LONGITUD])
{
    int y;
    for (y = 0; y < LONGITUD; y++)
    {
        int x;
        for (x = 0; x < LONGITUD; x++)
        {
            char actual = matriz[y][x];
            printf("| %c ", actual);
        }
        printf("|\n");
    }
}
void leeCodigo(char matriz[LONGITUD][LONGITUD])
{
    printf("Ingresa el codigo: ");
    scanf("%c", &codigoGlobal);
    char letra = 'A';
    int y = 0, x = 0;
    while (letra <= 'Z')
    {
        if (letra == codigoGlobal)
        {
            letra++;
        }

        // Comprobación extra para cuando el código es 'Z'
        if (letra <= 'Z')
        {
            matriz[y][x] = letra;
        }
        x++;
        letra++;
        if (x >= LONGITUD)
        {
            x = 0;
            y++;
        }
        if (y >= LONGITUD)
        {
            y = 0;
        }
    }
}

int buscarFila(char matriz[LONGITUD][LONGITUD], char busqueda)
{
    int y;
    for (y = 0; y < LONGITUD; y++)
    {
        int x;
        for (x = 0; x < LONGITUD; x++)
        {
            char actual = matriz[y][x];
            if (actual == busqueda)
            {
                return y;
            }
        }
    }
    return -1;
}

int buscarColumna(char matriz[LONGITUD][LONGITUD], char busqueda)
{
    int y;
    for (y = 0; y < LONGITUD; y++)
    {
        int x;
        for (x = 0; x < LONGITUD; x++)
        {
            char actual = matriz[y][x];
            if (actual == busqueda)
            {
                return x;
            }
        }
    }
    return -1;
}
char remplazoPrimera(char matriz[LONGITUD][LONGITUD], char primeraLetra, char segundaLetra)
{
    int columnaPrimera = buscarColumna(matriz, primeraLetra);
    int filaPrimera = buscarFila(matriz, primeraLetra);
    int columnaSegunda = buscarColumna(matriz, segundaLetra);
    int filaSegunda = buscarFila(matriz, segundaLetra);
    char remplazoPrimera = matriz[filaPrimera][columnaSegunda];
    return remplazoPrimera;
}

char remplazoSegunda(char matriz[LONGITUD][LONGITUD], char primeraLetra, char segundaLetra)
{
    int columnaPrimera = buscarColumna(matriz, primeraLetra);
    int filaPrimera = buscarFila(matriz, primeraLetra);
    int columnaSegunda = buscarColumna(matriz, segundaLetra);
    int filaSegunda = buscarFila(matriz, segundaLetra);
    char remplazoSegunda = matriz[filaSegunda][columnaPrimera];
    return remplazoSegunda;
}
void consumirNuevaLinea(void)
{
    int c;
    do
    {
        c = getchar();
    } while (c != EOF && c != '\n');
}
void leeTexto(char destino[MAXIMA_LONGITUD_CADENA])
{
    consumirNuevaLinea();
    printf("Ingresa el texto: ");
    fgets(destino, MAXIMA_LONGITUD_CADENA, stdin);
    //Remover salto de línea
    if ((longitudCadena(destino) > 0) && (destino[longitudCadena(destino) - 1] == '\n'))
    {
        destino[longitudCadena(destino) - 1] = '\0';
    }
}

void codifica(char texto[MAXIMA_LONGITUD_CADENA], char matriz[LONGITUD][LONGITUD])
{
    int longitud = longitudCadena(texto) - 1; // El -1 es para no tomar en cuenta el *
    int x = 0;
    while (x < longitud)
    {
        char primera = texto[x];
        if (x + 1 < longitud)
        {
            char segunda = texto[x + 1];
            if (primera != ' ' && segunda != ' ' && primera != codigoGlobal && segunda != codigoGlobal)
            {
                char nuevaPrimera = remplazoPrimera(matriz, primera, segunda);
                char nuevaSegunda = remplazoSegunda(matriz, primera, segunda);
                texto[x] = nuevaPrimera;
                texto[x + 1] = nuevaSegunda;
                x++;
            }
        }
        x++;
    }
}

void decodifica(char texto[MAXIMA_LONGITUD_CADENA], char matriz[LONGITUD][LONGITUD])
{
    // Se usa la misma función
    codifica(texto, matriz);
}

void muestraTexto(char texto[MAXIMA_LONGITUD_CADENA])
{
    printf("%s\n", texto);
}

Por cierto, en mi blog tengo más ejercicios resueltos en lenguaje C.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *