ACTUALIZACION 2: Ayuda Ejercicio 4.2 de "Illustrating C - Donald Alcock"

Iniciado por incubusinside, 11 Julio 2011, 04:54 AM

0 Miembros y 1 Visitante están viendo este tema.

incubusinside

Actualización 2. Por favor miren al final del post.

Hola!!, primero saludarlos y agradecer se pasen a ver este post. Ahora a lo que voy:
Tengo una gran problema con el ejercicio 4.2 del libro Illustrating C y es que empece a leerlo, segun para mejor mis pobres conocimientos de C y quede enganchado con este HDP.

Esto es lo que dice:


Y está es mi traducción:
CitarEscribe una funcion, usando una tabla estado-simbolo, que lea un numero octal del teclado, convirtiendolo en un entero decimal (o tipo 'long'). Permite un signo - o + precedente. Por ejemplo, el programa debe leer -74 y dar el resultado -60. Tu tabla de estado debe tener 4 columnas. Estas son: [ 0] para tratar con el primer signo + o -, [1] para trata con cualquier digito de 0 a 7, [2] para trata con el caracter espacio, [3] para tratar con cualquier otro caracter (un error). El valor en cada celda debe constar de una 'etiqueta' (para usar en asociacion con un "switch") y el numero del siguiente 'estado', o fila. El 'case' asociado con un digito valido debe multiplicar el resultado acumulado por la base del numero, 8, despues agregar el digito actual.

OK...bueno si se dan cuenta dice que utiliza una tabla de estado....y segun una parte del libro dice que es una tecnica muy utilizada....y hasta ahora es que veo esa tecnica en un libro (si saben de una aplición de esta técnica en el mundo real por favor pasenla!!)

Entonces empece...y ya llevo 3 dias sin poder pasar de ahi...
Antes de pasar algo de mi codigo, los voy a tratar de poner un poco al dia con este libro y las tablas de estado con ejemplo del mismo.

Aca parte del libro:


#include <stdio.h>
char Symbol [] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' };
long Table [16] [8] =
{
   { 100000, 50001, 10003, 5007, 1006, 512, 111, 0 },
   {      0,     0, 10002, 5007, 1006, 512, 111, 0 },
   {      0,     0, 10004, 5007, 1006, 512, 111, 0 },
   {  80005, 30005, 10004, 5007, 1006, 512, 111, 0 },
   {      0,     0, 10005, 5007, 1006, 512, 111, 0 },
   {      0,     0,     0, 5007, 1006, 512, 111, 0 },
   {      0,     0,  8010, 3010, 1009, 512, 111, 0 },
   {      0,     0,     0,    0, 1008, 512, 111, 0 },
   {      0,     0,     0,    0, 1009, 512, 111, 0 },
   {      0,     0,     0,    0, 1010, 512, 111, 0 },
   {      0,     0,     0,    0,    0, 512, 111, 0 },
   {      0,     0,     0,    0,  815, 315, 114, 0 },
   {      0,     0,     0,    0,    0,   0, 113, 0 },
   {      0,     0,     0,    0,    0,   0, 114, 0 },
   {      0,     0,     0,    0,    0,   0, 115, 0 },
   {      0,     0,     0,    0,    0,   0,   0, 0 }
};

int main ( void )
{
   long Entry = 1, Number = 0;
   int Column, Row = 0;
   char Ch;
   printf ("\nEnter a number\n");
   while ( ((Ch = getchar()) != '\n') && Entry )
   {
       for ( Column=0; Column<7 && (Ch != Symbol[Column]); ++Column );
       Entry = Table [Row][Column];
       Number += Entry / 100;
       Row = Entry % 100;
       printf(" %li ", Number);
   }
   //printf("%c,%c  ", Ch,'\n' && Entry);
   if (Entry)
       printf ("= %ld in Arabics", Number);
   else
       printf ("\nError");
   printf("\nEnd of run");
   return 0;
}


Y bueno resulta que trate de hacerlo algo por el estilo, pero no me cuadraba pues en este ejemplo el numero de columnas es igual al numero de simbolos y el ejercicio dice que una columna se encargara de los digitos...

Y les pongo un poco más del libro que es una pista para la solución:



Que dice que para el tipo de logica de tabla de simbolos y estados es util usar switch anidados: el externo lidia con los estados (filas) y en cada case de este abra un switch que lidia con los simbolos (columnas)...

y hasta ahora lo que llevo....que es nada...casi...

#include <stdio.h>

char Simbol [] = {'0', '1', '2', '3', '4', '5', '6', '7'};
char   Sign [] = {'+', '-'};

long Table [8] [4] =
{
    {  143,  100,   132,  0},
    {  145,  101,     0,  0},
    {    0,  102,     0,  0},
    {    0,  103,     0,  0},
    {    0,  104,     0,  0},
    {    0,  105,     0,  0},
    {    0,  106,     0,  0},
    {    0,  107,     0,  0}
};

int main ( void )
{
    long Entry = 1, Number = 0, Simbo;
    int Column=0, Row;
    int base = 8;
    char Ch;

    printf ("\nIntroduce un numero en base 8 (Octal)\n");
    while ( ((Ch = getchar()) != '\n') && Entry )
    {
        if( (Ch == '+') || ( Ch == '-') )
        {
            for ( Row=0; Row<2 && (Ch != Sign[Row]); ++Row );
        }
        else
        {
           for ( Row=0; Row<8 && (Ch != Simbol[Row]); ++Row );
           Column = 1;
        }

        Entry = Table [Row][Column];
        Simbo = Entry % 100;


        printf("Number %li Simbo %li Column %i \n", Number, Simbo, Column);
        switch (Row)
        {
          case 0:
                switch (Simbo)
                {
                   case 43:{
                           printf("Entro y es un +\n");
                           Entry = Table [Row][Column];
                           Column = Entry / 100;
                           Number= (+1)*Number;
                           break;}
                   case 0: {
                          Number = ((Number*base) +Simbo);
                          Entry = Table [Row][Column];
                          Column = Entry / 100;
                          break;
                          }
                   case 2: break;
                   case 3: break;
                   default: printf("caso 0\n");
                }
                break;

          case 1:
                switch (Simbo)
                {
                   case 45:{
                           printf("Entro y es un -\n");
                           Entry = Table [Row][Column];
                           Column = Entry / 100;
                           Number= (-1)*Number;
                           break;
                           }
                   case 1: {
                          Number = ((Number*base) +Simbo);
                          Entry = Table [Row][Column];
                          Column = Entry / 100;
                          break;
                          }
                   case 2: break;
                   case 3: break;
                   default: printf("caso 1\n");
                }
                break;

          case 2:
                switch (Simbo)
                {
                   case 0: break;
                   case 2:{
                          Number = ((Number*base) +Simbo);
                          Entry = Table [Row][Column];
                          Column = Entry / 100;
                          break;
                          }
                   default: printf("caso 2\n");
                }
                break;

          case 3:
                switch (Simbo)
                {
                   case 0: break;
                   case 3:{
                          Number = ((Number*base) +Simbo);
                          Entry = Table [Row][Column];
                          Column = Entry / 100;
                          break;
                          }
                   default: printf("caso 3\n");
                }
                break;

          case 4:
                switch (Simbo)
                {
                   case 0: break;
                   case 4:{
                          Number = ((Number*base) +Simbo);
                          Entry = Table [Row][Column];
                          Column = Entry / 100;
                          break;
                          }

                   default: printf("caso 4\n");
                }
                break;

          case 5:
                switch (Simbo)
                {
                   case 0: break;
                   case 5:{
                          Number = ((Number*base) +Simbo);
                          Entry = Table [Row][Column];
                          Column = Entry / 100;
                          break;
                          }

                   default: printf("caso 5\n");
                }
                break;

          case 6:
                switch (Simbo)
                {
                   case 0: break;
                   case 6:{
                          Number = ((Number*base) +Simbo);
                          Entry = Table [Row][Column];
                          Column = Entry / 100;
                          break;
                          }
                   default: printf("caso 6\n");
                }
                break;

          case 7:
                switch (Simbo)
                {
                   case 0:  break;
                   case 7:{
                          Number = ((Number*base) + Simbo);
                          Entry = Table [Row][Column];
                          Column = Entry / 100;
                          break;
                          }
                   default: printf("caso 7\n");
                }
                break;

        default: printf("\ndefault\n");
        }

        printf("\n---Number %li\n\n", Number);

    }
     if (Entry)
         printf ("\n\n= %ld en Decimal", Number);
     else
        printf ("\nError");
     return 0;
}


Actualización 2
Bueno tengo este codigo que si hace la conversion para eso esta esta linea de codigo
Number = ((Number*base) + Simbo);
que como decia el texto se tenia que multiplicar la base por el resultado acumulado y despues añadir el digito actual. Ademas ya acepta el + y - y tambien si no tiene signo (esto un poco truqueado pero bueno...) solo faltaria multiplicar el resultado por el signo para que sea la conversion adecuada. AUn asi no es exactamente lo que se pide en el problema primero por que no estoy utilizando las filas como estados mas bien las columnas y ademas no se que hacer con el caracter espacio que dice debe estar en la columna 3.... Bueno si alguien tiene un comentario o algo que preguntar haganmelo saber. Saludos.

Actualizacion 1: Como dije ya mas o menos lo mejore.
Sigo teniendo problemas con la base. Pense en hacer una funcion que hiciera esto:

r=numero;
   while (c!=potencia)
   {
      r= r*numero;
      c=c+1;
   }


Pero despues de releer el problema para se que es asi como se debe calcular:

por ejemplo 123 (octal):
1 iteracion  1*8=8
2 iteracion (2+8)*8=80
3 iteracion 80+3= 83 (decimal)

Aun asi tengo problema para implementar esta parte.

Ademas quisiera que ademas de aceptar + y - se pudiera ingresar el numero asi como tal 77.

Bueno si alguien puede ayudarme se los agradeceria. Saludos