elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  verificar numeros romanos
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] Ir Abajo Respuesta Imprimir
Autor Tema: verificar numeros romanos  (Leído 10,752 veces)
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: verificar numeros romanos
« Respuesta #10 en: 20 Agosto 2013, 11:03 am »

break/continue representan saltos, pero son saltos estructurados y relativamente claros. Su mala fama se debe a que pongas un break donde no debes y se salte el bucle creando errores extraños. Eso hace que su abuso sea un gran problema, como programador debes decidir si queda claro o confuso su uso en el contexto actual. Como regla general, suelo poner un solo break/continue por bucle y intento que sea al principio, porque se ven más explícitos.

En el código que he propuesto, el uso de break me permite ahorrarme el uso de una variable bandera y se ve bastante claro. Por lo que lo considero adecuado.

Los continue me parecen bastante importantes, imaginate que estas usando un for anidado:

Código
  1. for (short i = 0; i < 100;i++)
  2.   for (short j = 0; j < 100;j++)
  3.   {
  4.        // Codigo...
  5.   }

Y quieres evitar que se haga una iteracion en la cual i = j. Podrías poner algo tal que asi:

Código
  1. for (short i = 0; i < 100;i++)
  2.   for (short j = 0; j < 100;j++)
  3.   {
  4.        if (i != j)
  5.        {
  6.            // Codigo...
  7.        }    
  8.   }

Pero eso implica más llaves y más bloques de codigo. El uso de continue te permite saltarse la iteracion de una forma bastante explícita y clara:

Código
  1. for (short i = 0; i < 100;i++)
  2.   for (short j = 0; j < 100;j++)
  3.   {
  4.        if (i == j) continue;
  5.  
  6.        // Codigo...
  7.   }

los profesores nos prohibían estas instrucciones debido a que utilizar un break/continue es equivalante a la instrucción goto: estás "saltando" desde un punto del bucle a otro modificando el curso de ejecución del programa.
Ojo con ese argumento, las llamadas a función también son saltos de ejecución del programa.


En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
Alien-Z

Desconectado Desconectado

Mensajes: 177


C++ Programmer


Ver Perfil
Re: verificar numeros romanos
« Respuesta #11 en: 20 Agosto 2013, 12:53 pm »

Citar
Ojo con ese argumento, las llamadas a función también son saltos de ejecución del programa.

Si, pero no son saltos desde el punto de vista del programador sino del programa, cuando hablamos de la prohibición de break/continue/goto no nos referimos a que sea ineficiente realizar estos saltos sino que no son claros a la hora de trabajar el código. Si en mi programa escribo la función "dividir(..)" tanto yo como cualquier otro informático comprenderá qué estamos diviendo X entre Y independientemente de las veces que llame a esta función; sin embargo si en un bucle pongo 3 o 4 break/continue, por lo general otra persona que intente leerlo le va a costar bastante comprenderlo.

Por tanto considero que el argumento citado por los catedráticos es válido.

¿Deberíamos dejarlo en un punto intermedio y usar estas instrucciones con cabeza?, en teoría no habría problema pero igual que con el famoso goto veríamos mucho abuso, por eso gran parte de los informáticos no recomiendan incluirlas en el programa; pero por supuesto la instrucción está ahi y cada uno puede darle el uso que crea conveniente.

Un saludo.


« Última modificación: 20 Agosto 2013, 13:00 pm por Alien-Z » En línea

m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: verificar numeros romanos
« Respuesta #12 en: 21 Agosto 2013, 04:56 am »

amchacon ya le puse lo que me dijiste en la condicion *ptr!= '\n' && *ptr!='\0'
y no me funciona aun, sigo teniendo el mismo problema de que aunque le ponga un numero romano me imprime que no es

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define TAM 10
  4.  
  5. int main()
  6. {
  7.    int i,j,bandera;
  8.    char romano[TAM],letras[]={'I','V','X','L','C','D','M','\0'},*ptr,*p;
  9.    printf("Dame el primer numero: ");
  10.    fgets(romano,TAM,stdin);
  11.    ptr = romano;
  12.    p = letras;
  13.    for(i=*ptr;((*ptr!='\0')&&(*ptr!= '\n'));*ptr++)
  14.    {
  15.        bandera = 0;
  16.        for(j=*p;(((*p!='\0')&&(*ptr!='\n'))&&(bandera==0));*p++)
  17.        {
  18.            if(*ptr == *p)
  19.               bandera = 1;
  20.        }
  21.        if(!bandera)
  22.        {
  23.            printf("Error!No es numero romano\n");
  24.            exit(1);
  25.        }
  26.    }
  27.    return 0;
  28. }
En línea

Alien-Z

Desconectado Desconectado

Mensajes: 177


C++ Programmer


Ver Perfil
Re: verificar numeros romanos
« Respuesta #13 en: 21 Agosto 2013, 11:09 am »

Tiene un par de errores, te lo pongo corregido:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define TAM 10
  5.  
  6. int main () {
  7.  
  8.    char alfRomano[] = {'I','V','X','L','C','D','M','\0'}, entrada[TAM], *pAlfRomano, *pEntrada;
  9.    bool encontrado;
  10.  
  11.    printf("Introduce un numero: ");
  12.    fgets(entrada, TAM, stdin);
  13.  
  14.    for(pEntrada = entrada; *pEntrada != '\n'; pEntrada++) { //Bucle exterior: recorre la entrada letra por letra
  15.  
  16.        encontrado = false;
  17.        for(pAlfRomano = alfRomano; ((*pAlfRomano != '\0') && !encontrado); pAlfRomano++) { //Bucle interior: comprueba si el siguiente carácter es romano
  18.            if(*pEntrada == *pAlfRomano) encontrado = true;
  19.        }
  20.  
  21.        if(!encontrado) {
  22.            printf("No es un numero romano.\n");
  23.            exit(1);
  24.        }
  25.    }
  26.  
  27.    printf("Es un numero romano.\n");
  28.  
  29.    return 0;
  30. }
  31.  

Casos especiales:

-Si introduces la cadena vacía te la da por correcta y eso no es un número romano.
-Si introduces un número romano correcto y al final un espacio te la da por incorrecta cuando si es válida.

Esto es muy sencillo de manejar pero ya corre por tu cuenta.

Además puedes mejorar el código y añadirle reglas de la sintáxis romana como por ejemplo que no se puedan escribir más de tres carácteres iguales consecutivos: VIIII -> mal

Saludos.
« Última modificación: 21 Agosto 2013, 11:21 am por Alien-Z » En línea

m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: verificar numeros romanos
« Respuesta #14 en: 22 Agosto 2013, 01:19 am »

Saludos Alien-Z ya por fin pude encontrar el error, estaba en el puntero del segundo for, cada vez que entraba de nuevo al 2do ciclo el puntero no se reiniciaba  a la primera posicion, pero ya lo pude corregir

Código
  1. int main()
  2. {
  3.    int i,j,bandera;
  4.    char romano[TAM],letras[]={'I','V','X','L','C','D','M','\0'},*ptr,*p;
  5.    printf("Dame el primer numero: ");
  6.    gets(romano);
  7.    ptr = romano;
  8.    p = letras;
  9.    for(i=*ptr;*ptr!='\0';*ptr++)
  10.    {
  11.        bandera = 0;
  12.        for(j=0;((j<7)&&(bandera==0));j++)
  13.        {
  14.            if(*ptr == *(p+j))
  15.               bandera = 1;
  16.        }
  17.        if(!bandera)
  18.        {
  19.            printf("Error!No es numero romano\n");
  20.            exit(1);
  21.        }
  22.    }
  23.    return 0;
  24. }

muchas gracias
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: verificar numeros romanos
« Respuesta #15 en: 22 Agosto 2013, 08:46 am »

por fin pude encontrar el error, estaba en el puntero del segundo for, cada vez que entraba de nuevo al 2do ciclo el puntero no se reiniciaba  a la primera posicion, pero ya lo pude corregir
Algunos comentarios sobre ese programa:

* Faltan los encabezados.
* Si vas a imprimir una cadena en la salida estándar y esta no termina con el carácter '\n' debes vaciar su bufer de forma explicita mediante la llamada "fflush(stdout);".
* No utilices gets, la razón de ello se explica en el tema |Lo que no hay que hacer en C/C++. Nivel basico|.
* Para terminar la función principal no es necesario llamar a la función exit, puedes utilizar la sentencia "return N;" con el mismo efecto.

Por ultimo como ya comento eferion se puede utilizar la función strchr (prototipo en <string.h>) para acortar el programa a un solo bucle. Mas o menos así:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define NUM_CHARS  7
  6.  
  7. int main(void)
  8. {
  9.   char num[NUM_CHARS];
  10.   int i;
  11.  
  12.   printf("Dame el primer numero: ");
  13.   fflush(stdout);
  14.   if (fgets(num, NUM_CHARS, stdin) == NULL)
  15.      return EXIT_FAILURE;
  16.  
  17.   for (i = 0; strchr("IVXLCDM", num[i]) != NULL; i++)
  18.      ;
  19.   if (i > 0 && (num[i] == '\n' || num[i] == '\0'))
  20.      puts("OK");
  21.   else
  22.      puts("Entrada no valida");
  23.  
  24.   return EXIT_SUCCESS;
  25. }
Con la limitante de indicar una entrada no valida si la linea empieza con espacio blanco.

Otra opción consiste en sustituir el bucle basado en strchr por una llamada a strspn.

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
Páginas: 1 [2] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Calculadora que suma numeros romanos
Programación C/C++
miiku 1 10,304 Último mensaje 13 Agosto 2012, 03:50 am
por farresito
Numeros Romanos « 1 2 3 »
Programación C/C++
05K4R1N 20 13,524 Último mensaje 11 Junio 2013, 02:33 am
por edr89
Pasar numeros enteros arábigos a romanos, por donde empezar. « 1 2 3 »
Programación C/C++
Caster 21 12,558 Último mensaje 18 Mayo 2014, 18:38 pm
por Blaster
[Aporte]Convertidor de números decimales a romanos
Programación C/C++
0xFer 0 3,221 Último mensaje 24 Mayo 2015, 19:00 pm
por 0xFer
Conversor de números arábigos a números romanos
Programación C/C++
perico1995 0 1,881 Último mensaje 19 Diciembre 2017, 17:54 pm
por perico1995
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines