Ver Mensaje Individual
  #48 (permalink)  
Antiguo 20/06/2014, 06:53
Avatar de leosansan
leosansan
 
Fecha de Ingreso: mayo-2012
Ubicación: GRAN CANARIA
Mensajes: 194
Antigüedad: 12 años, 6 meses
Puntos: 49
Respuesta: Atascado con ejercicio.

Antes que nada editar mi último código al que faltaba una línea:

Código C++:
Ver original
  1. #include <iostream>
  2. #include <cctype>  /// para usar la funcion "isdigit"
  3. #include <cstring> /// para usar la funcion "strcmp", "strcat", "strlen"
  4. #include <cstdlib> /// para usar la funcion "itoa"
  5. #include <cstdio>  /// para usar la funcion "sprintf"
  6. #define N 10
  7.  
  8. using namespace std;
  9.  
  10. bool incrementar( char numero[N] );
  11.  
  12. int main(){
  13.     char lista[N] = {0}, num [N] = {0};
  14.   for( int i = 0; i < N - 1; i++ ){
  15.     cout << "Ingrese parametro " << i + 1 << " de string: ";
  16.     cin >> lista[i];
  17.   }
  18.     cout  << endl << "Cadena inicial: " << lista << endl;
  19.     if ( !incrementar( lista) )
  20.     cout << "Lo siento la cadena no puede ser tratada." << endl;
  21.     else
  22.     cout << "Cadena incrementada: " << lista << endl;
  23.     return 0;
  24. }
  25.  
  26. bool incrementar(char numero[N]){
  27.   char nueves [N] = {0}, num [N] = {0};
  28.   int i;
  29.   for( i = 0; i < N - 1; i++ )
  30.     nueves [i] = '9';
  31.   for( i = 0; i < N - 1; i++ )
  32.     if ( !isdigit(numero[i]) )
  33.       return false;
  34.   if ( strcmp ( numero, nueves ) == 0 ){
  35.     sprintf( numero, "%d", 0 );
  36.     return true;
  37.   }
  38.   sprintf( num, "%d", atoi ( numero ) + 1 );
  39.   for  ( i = 0; i < N - 1 - strlen( num ); i++ )
  40.     numero[i] = '0';
  41.   numero[i] = '\0';
  42.   strcat ( numero, num );
  43.   return true;
  44. }

Como comenta dehm es un ejercicio para aprender con lo que con este y el de fightmx tienes para ir viendo el uso de algunas de las funciones de C++.

¿Quién dijo funciones?. Porque si, como comenta dehm es un ejercicio para aprender arrays y manejar el uso de los for e if podemos prescindir "totalmente" de dichas funciones. El código que resulta es un pelín más complejo que con funciones pero en él tienes el control total de lo que hace el código. Como yo soy más de C estoy acostumbrado a no tener la cantidad de funciones que tiene el C++, pero eso no es más que un reto ya que las tengo que implementar yo. Observa la ausencia de las librerías y funciones del código anterior:

Código C++:
Ver original
  1. #include <iostream>
  2. #define N 5
  3.  
  4. using namespace std;
  5.  
  6. bool incrementar( char numero[N] );
  7.  
  8. int main(){
  9.   char lista[N] = {0};
  10.   for( int i = 0; i < N - 1; i++ ){
  11.     cout << "Ingrese parametro " << i + 1 << " de string: ";
  12.     cin >> lista[i];
  13.   }
  14.     cout  << endl << "Cadena inicial: " << lista << endl;
  15.     if ( !incrementar( lista) )
  16.     cout << "Lo siento la cadena no puede ser tratada." << endl;
  17.     else
  18.     cout << "Cadena incrementada: " << lista << endl;
  19.     return 0;
  20. }
  21.  
  22. bool incrementar(char numero[N]){
  23.   int i, lon = 0, cont = 0, factor = 10, num = 0, num_ = 0;
  24.   for( i=0; i < N - 1; i++ )
  25.     if ( numero[i] < '0' || numero[i] > '9' )
  26.       return false;
  27.   for( i=0; i < N - 1; i++ )
  28.     if ( numero [i] == '9' )
  29.       cont++;
  30.   if ( cont == N - 1 ){
  31.     numero[0] = '0', numero[1] = '\0';
  32.     return true;
  33.   }
  34.   for( i=0; i < N - 1; i++ )
  35.     num =  num * factor + numero[i] - '0';
  36.   num_ = ++num;
  37.   for( lon = 0,factor = 1; num_; lon++, num_ /= 10,factor *= 10);
  38.   for  ( i = 0; i < N - 1 - lon; i++ )
  39.      numero[i] = '0';
  40.   for  ( i=N-1-lon, factor/= 10; i<N-1; i++, num -=(num/factor)*factor, factor/=10 )
  41.     numero[i] = num/factor + '0';
  42.   numero[i] = '\0';
  43.   return true;
  44. }

Y claro, así a pelo puede resultarte chino, pero como tan acertadamente plantea vangodp, cuya opinión comparto, para eso estamos aquí, para ayudarnos no sólo a colgar códigos sino a explicarlos cuando es necesario, y creo que en este caso lo es.

Así que ahí va el código comentado:

Código C++:
Ver original
  1. /******************   Codigo comentado   ************************/
  2.  
  3. bool incrementar(char numero[N]){
  4.   int i, lon = 0, cont = 0, factor = 10, num = 0, num_ = 0;
  5.  
  6. /// En este primer for compruebo si todos los caracteres de la cadena "numero" son '0' al '9'
  7.  
  8.   for( i=0; i < N - 1; i++ )
  9.     if ( numero[i] < '0' || numero[i] > '9' )
  10.  
  11. /// Si alguno no lo es devuelvo "false"
  12.  
  13.       return false;
  14.  
  15. /// Si entro aqui es que todos los caracteres son del tipo '0'  al '9'
  16. /// Y lo que hago es contar con la variable "cont" los 9 que hay
  17.  
  18.   for( i=0; i < N - 1; i++ )
  19.     if ( numero [i] == '9' )
  20.       cont++;
  21.  
  22. /// Si tengo N-1=9 tengo que devolver "0"
  23.  
  24.   if ( cont == N - 1 ){
  25.  
  26. /// Y lo hago haciendo que el primer caracter de la cadena,numero[0], sea '0'
  27. ///y el segundo y ultimo es el caracter nulo que cierra las cadenas:numero[1] = '\0'
  28.  
  29.     numero[0] = '0', numero[1] = '\0';
  30.  
  31. /// Y retorno true teniendo en cuenta que numero será esta vez "0"
  32.  
  33.     return true;
  34.   }
  35.  
  36. /// Si llego aqui es que NO todos los caracteres eran nueve
  37. /// Con lo que lo primero que necesito es el equivalente en
  38. /// tipo int del numero que representa la cadena "numero"
  39. /// Eso se hace multiplicando sucesivamente por 10 cada caracter,
  40. /// pasado a int, y se pasa de char a int sumando '0', o su equivalentte ASCII 48
  41. /// Aqui te aconsejo que mires la tabla de codigos ASCII, busca en google...
  42. /// por ejempño si numero[i]='2' el entero 2 equivalente seria: 2 = numero[i] - '0'
  43.  
  44. /// Y lo de "num =  num * factor + numero[i] - '0'" funciona asi:
  45.  
  46. /// Imagina que numero[5]="1234", es decir
  47. /// numero[0] = '1' | numero[1] = '2' |  numero[2] = '3' | numero[3] = '4'
  48. /// y actua el for:actua el for:
  49. ///
  50. /// num =  0   * 10 + (numero[0] - '0') = 0*10+1 = 1
  51. /// num =  1   * 10 + (numero[1] - '0') = 1*10+2 = 12
  52. /// num =  12  * 10 + (numero[2] - '0') = 12*10+3 = 123
  53. /// num =  123 * 10 + (numero[3] - '0') = 123*10+4 = 1234
  54.  
  55. /// Tachin, Tachan, ya tenemos num = 1234 pero ahora como un int
  56.  
  57.   for( i=0; i < N - 1; i++ )
  58.     num =  num * factor + numero[i] - '0';
  59.  
  60. /// Ahora lo incremento y copio para no perderlo en las siguientes operaciones
  61.  
  62.   num_ = ++num;
  63.  
  64. /// Ahora viene un for "especial", si te fijas acaba en punto y coma, no tiene cuerpo
  65. /// Ello es porque solo voy a iterar para conseguir dos cosas:
  66. /// 1. El tamaño de la variable entera num, que no tiene porque coincidir con la de "numero"
  67. /// 2. La variable "factor" que sera de 10000, si N=5 para el caso de "1235"
  68. /// Y no, no me he equivocado, recuerda que ya hemos incrementado el "1234"
  69.  
  70.   for( lon = 0,factor = 1; num_; lon++, num_ /= 10,factor *= 10);
  71.  
  72. /// Copio al comienzo de la "numero" los ceros que corresponden a la diferencia entre el
  73. /// tamaño de "numero" = N-1  y el de "num" = lon
  74.  
  75.   for  ( i = 0; i < N - 1 - lon; i++ )
  76.      numero[i] = '0';
  77.  
  78. /// Y continuo rellenado la cadena "numero" pero esta vez con los digitos de "num"
  79. ///Es decir, viene justo lo contrario a lo de antes: pasar "num" a "numero"
  80. /// Y si antes para pasar del char numero[i] a entero restaba '0', ahora sumare '0'
  81. /// Y el proceso del for seria este:
  82.  
  83. /// Ocurre una cosa muy importante: (1235/1000)*1000 no es 1235
  84. /// porque la division (1235/1000) es entre enteros y da 1 con lo que queda:
  85.  
  86. /// 1.1  numero[0] = 1235/1000 + '0' = 1 + '0' = '1'
  87. /// 1.2 NEW num -=(num/factor)*factor,factor/=10
  88. ///      o  num  = num -(num/factor)*factor
  89. ///     ==> num = 1235-(1235/1000) * 1000 = 1235-1*1000 = 235
  90.  
  91. /// 2.1 numero[1] = 235/100 + '0' = '2'
  92. /// 2.2 num = 235-(235/100)*100 = 235-2*100 = 235-200 = 35
  93.  
  94. /// 3.1 numero[2] = 35/10 + '0' = '3'
  95. /// 3.2 num = 35-(35/10)*10 = 35-3*10 = 35-30 = 5
  96.  
  97. /// 4.1 numero[3] = 5/1 + '0' = '5'
  98. /// 4.2 num = 5-(5/10)*1 = 5-5*1 = 0
  99.  
  100.   for  ( i=N-1-lon, factor/= 10; i < N-1; i++, num -=(num/factor)*factor, factor/=10 )
  101.     numero[i] = num/factor + '0';
  102.  
  103. /// Y se acabo el for con el resultado de:
  104. ///numero[0] = '1' | numero[1] = '2' |  numero[2] = '3' | numero[3] = '5'
  105. ///Es decir con la cadena: numero[]="1235"
  106.  
  107. /// Y ahora añadimos el caracter de fin de cadena
  108.  
  109.   numero[i] = '\0';
  110.  
  111. /// Oberva que he puesto numero[i] = '\0' esto es porque
  112. ///la i se ha incrementado en la última pasada del for
  113. /// y su valor es ahora justito N-1, que lo podia haber puesto
  114. /// en lugar de la i, pero queda más geek.
  115.  
  116. /// Y ya solo no queda indicar el retorno, true, claro
  117.  
  118.   return true;
  119.  
  120. }/******************   Codigo comentado   ************************/


Espero te sea útil y si te queda alguna duda del ejercicio a dar la lata que para eso estamos aquí.

¡¡¡Saluditos!!!


Última edición por leosansan; 20/06/2014 a las 09:06