1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
// 3x06: Compresión y descompresión de cadenas /* Reescribe el programa anterior para que haga lo mismo pero para comprimir y descomprimir líneas de caracteres, sin que sea necesario acabar con un ‘.’. Se debe de leer directamente una línea completa como una cadena de caracteres. */ /* Problemas conocidos: En el programa se ha considerado que una secuencia de caracteres solo esta compuesta de letras, por lo que si se encuentra una barra se entiende que después ha de ir un numero de uno o mas dígitos que multiplicara el siguiente carácter que será una letra. */ #include <stdio.h> #include <string.h> main(){ enum opcciones{ secuencia=1, comprimido=2, salir=3 } opc; int eleccion; char exit; char cadena[100]; int i, j; int cont; int multiplicador; // Repetición del programa hasta que se decida salir: do{ system("clear"); // Menú de selección: printf("Elija una de las siguientes opciones:\n"); printf(" 1. Convertir una secuencia a formato comprimido.\n"); printf(" 2. Pasar de formato comprimido a una secuencia.\n"); printf(" 3. Salir\n\v"); do{ scanf( "%i", &eleccion ); }while( eleccion < 1 || eleccion > 3 ); opc = (enum opcciones)(eleccion); i=0; cont = 0; // Se pasa de secuencia a RLE: if( eleccion == secuencia ){ // Se solicita un conjunto de caracteres. printf("Introduzca la secuencia, ejemplo: \"aaaaaaabbccccddde\"\n\v"); scanf( "%s", cadena ); // Se imprime/calcula el resultado: printf("\n Su cadena comprimida es:\n\v "); // Se realiza un bucle desde el componente 0 al componente maximo, ambos incluidos: (el ultimo tiene un \n pero es necesario hacer el bucle para imprimir el ultimo resultado. for( i=0; i<=strlen(cadena); i++ ){ //Si es la primera vuelta se cuenta +1 if( i==0 ){ cont++; } else if( cadena[i] != '\n' && cadena[i-1] == cadena[i] ){ // Si el caracter no es un fin de cadena y el componente anterior es igual al actual: cont++; //Se suma +1 } else{ // En caso de ser caracteres diferentes o de terminarse la cadena: // Si se han contabilizado al menos 4 caracteres iguales: if( cont >= 4 ){ printf("\\%i%c", cont, cadena[i-1] ); // Se imprime el carácter comprimido. } else{ // En caso contrario: //Se imprime el carácter de 1 a 3 veces segun marque el contador: for( j=1; j<=cont; j++ ){ printf("%c", cadena[i-1] ); }; }; // Se termina poniendo el contador a 1 contabilizando el nuevo carácter: cont = 1; }; }; printf("\n\v"); }; // Se pasa de RLE a secuencia: if( eleccion == comprimido ){ // Se solicita la secuencia comprimida: printf("Introduzca la secuencia comprimida, ejemplo: \"\\7abb\\4cddde\"\n\v"); scanf( "%s", cadena ); // Se imprime/calcula el resultado: printf("\n Su cadena descomprimida es:\n\v "); // Se realiza un bucle desde el componente 0 al ultimo, ambos incluidos. for( i=0; i<=strlen(cadena); i++ ){ // Cuando se encuentre una contrabarra... if( cadena[i] == '\\' ){ multiplicador = 0; // Se haya el multiplicador, para ello se comprueba si ese ASCII corresponde a un numero: Ejemplo ASCII 50 - 48 = 2, entonces si el carácter esta entre 0 y 9 se guarda... // Darse cuenta que j empieza en uno y no en cero para empezar en el componente 1 y no en \ de nuevo. (realmente es para ahorrarnos en los vectores sumar un +1 ademas del +j) for( j=1; cadena[i+j]-48 >= 0 && cadena[i+j]-48 <= 9; j++ ){ multiplicador *= 10; // Primero se multiplica por 10 convirtiendo el el numero de unidad a décima. multiplicador += cadena[i+j] - 48; // Ahora se suma el carácter ASCII-48 }; i = i+j; // Se ha de dejar la i preparada para hallar el carácter a multiplicar, por lo que se le suma j que es el numero de componentes que se usaron. // Por ultimo se imprime el carácter tantas veces como marque el multiplicador for( j=1; j <= multiplicador; j++ ){ printf( "%c", cadena[i] ); }; } else{ // En caso contrario imprime la letra sin mas: printf( "%c", cadena[i] ); }; }; printf("\n\v"); }; // Se continúa el programa después de pulsar intro: if( eleccion != salir ){ printf("Pulse intro para mostrar el menu.\n"); scanf("%c", &exit); do{ scanf("%c", &exit); }while( exit != '\n' ); }; }while( eleccion != salir ); system("clear"); }; |