Ver Mensaje Individual
  #69 (permalink)  
Antiguo 03/12/2014, 01:23
Avatar de leosansan
leosansan
 
Fecha de Ingreso: mayo-2012
Ubicación: GRAN CANARIA
Mensajes: 194
Antigüedad: 12 años
Puntos: 49
Respuesta: Petando la pila. Problemas y retos usando recursividad.

Cita:
Iniciado por vangodp Ver Mensaje
Me gustan los operadores ternarios =). Sin embargo a las funciones recursivas me estan dando sudores. jajaja
Y a mi me encantan. Me recuerdan a cuando daba clases y enseñaba un método diferente al usado normalmente por los alumnos pero de gran potencia que reducía los cálculos en en orden de diez. Al principio se resistían a dejar lo conocido pero al cabo de unas semana, y después de probarlo varias veces ya no había vuelta atrás: se quedaban con el nuevo método. Y es que lo nuevo y mejor cuesta al principio, pero una vez que le coges el tranquillo ya no lo sueltas. Estoy seguro que si algunos de los que han opinado en contra del operador condicional, incluido el encadenado, lo ponen en práctica cuatro o cinco veces ya no podrán prescindir de él.

Y respecto a las funciones recursivas amigo vangodp te aconsejo que empieces por algunas"suaves", poco a poco le oras cogiendo el truquillo. Aunque yo la verdad es que donde esté un for o parecido..........

Y hablando del operador condicional, ahí va el primer ejercicio de la segunda tanda ....

Código C++:
Ver original
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. char* no_Rep ( char *dest , const char *orig , int i , int j ) {
  5.   return (orig [i]=='\0') ? dest [j]='\0' : orig[i]!=orig[i-1] ? dest[j]=orig[i-1], no_Rep(dest,orig,i+1,j+1) : no_Rep(dest,orig,i+1,j),dest ;
  6. }
  7.  
  8. char* noRep(char* destino, const char* origen) {
  9.   return no_Rep ( destino , origen , 1 , 0 ) ;
  10. }
  11.  
  12. int main ( void ) {
  13.   char origen [ ] = "abccccfabaddeff" , destino [ strlen ( origen ) + 1 ] ;
  14.   return printf ( "%s ==> %s\n" , origen , noRep ( destino , origen ) ) , 0;
  15. }



Aprovecho para corregir un pequeño detalle del segundo ejercicio que puse en primer lugar, el de las combinaciones, ya que tenía el tamaño de un array mal dimensionado:

Código C++:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int esVampiro ( int num ) ;
  6. void variaciones_sin_repe ( char numero [ ] , int tam , int permutacioneS , char aux [ ] , char Npermutacion [ permutacioneS ][ tam + 1 ] , int n0 , int n ) ;
  7.  
  8. int main( void ) {
  9.   int num = 13078260 ;
  10.   return printf ( "\n!!! Como lo quiere Pantalaimon ( 0 - 1 ) !!! ==> : [%d]\n\n" , esVampiro ( num ) ) , 0 ;
  11. }
  12.  
  13. int esVampiro (  num ) {
  14.   int i , j , n , tam , permutacioneS = 1 , num0 = num ;
  15.   for ( tam = 1 ; num0 ; tam++ , num0 /= 10 ) ;
  16.   char numero [ tam + 1 ] ;
  17.   if ( tam %2 == 0 )
  18.     return puts ( "NO ES VAMPIRO por numero impar de cifras." ) , 0 ;
  19.   itoa ( num , numero , 10 ) ;
  20.   n = tam / 2 ;
  21.   for( i = 1 , permutacioneS *= ( tam - 1 ) ; i <  n ; ++i , permutacioneS *= ( tam - 1) ) ;
  22.   char aux [ tam + 1 ] , Npermutacion [ permutacioneS ][ tam + 1 ] ;
  23.   variaciones_sin_repe ( numero , tam , permutacioneS , aux , Npermutacion , n, n ) ;
  24.   for( i = 0 ; i < permutacioneS ; i++ )
  25.     for( j = 0 ; j < permutacioneS ; j++ )
  26.       if ( Npermutacion [ i ][ 0 ] == 0 && Npermutacion [ i ][ 0 ] == 0 )
  27.         continue ;
  28.       else if ( ( Npermutacion [ i ][ tam / 2 - 1 ] != 0 || Npermutacion [ i ][ tam / 2 - 1 ] != 0 ) && atoi ( Npermutacion [ i ] ) * atoi ( Npermutacion [ j ] ) == num  ) {
  29.         return printf ( "\nES VAMPIRO: %d = %d * %d\n" , atoi ( Npermutacion [ i ] ) * atoi ( Npermutacion [ j ] ) , atoi ( Npermutacion [ i ] ) , atoi ( Npermutacion [ j ] ) ) , 1 ;
  30.   }
  31.   return puts ( "NO ES VAMPIRO" ) , 0 ;
  32. }
  33.  
  34. void variaciones_sin_repe( char numero [ ] , int tam , int permutacioneS , char aux [ ] , char Npermutacion [ permutacioneS ][ tam + 1 ] , int n0 , int n ){
  35.   int  i ;
  36.   static int j = 0 , permutaciones = 1  ;
  37.   if( n != 0 )
  38.     for( i = 0 ; i < tam - 1 ; ++i ) {
  39.       aux [ j ] = numero [ i ] ;
  40.       ++j ;
  41.       variaciones_sin_repe ( numero , tam , permutacioneS , aux, Npermutacion , n0 , n - 1 );
  42.       --j;
  43.     }
  44.   else {
  45.     aux [ n0 ] = '\0' ;
  46.     strcpy ( Npermutacion [ permutaciones - 1 ] , aux ) ;
  47.     permutaciones++ ;
  48.   }
  49. }

Y ya puestos edito mi segunda opción, toda ella recursiva les recuerdo, pero que ahora muestra los distintos colmillos caso de que los tenga el "vampiro":

Código C++:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int cantidadDigitos ( int num ) ;
  5. int esVampiro ( int numero ) ;
  6. int obtenerNumMinimo ( int digitos ) ;
  7. int obtenerNumMaximo ( int digitos )  ;
  8. int probar ( int numero , int num_1 , int num_0 , int n_minimo , int n_maximo , int digitos , int DigitosNumero [ 10 ] ) ;
  9. int DigitosNumero ( int digitosNumero [ 10 ], int numero , int flag )  ;
  10.  
  11. int main ( ) {
  12.   int numero = 13078260 ;
  13.   return printf ( "\n!!! Como lo quiere Pantalaimon ( 0 - 1 ) !!! ==> : [%d]\n\n" , esVampiro ( numero ) ) , 0 ;
  14.   return 0;
  15. }
  16.  
  17. int cantidadDigitos ( int num ) {
  18.   return ( num == 0 ) ? 0 : 1 + cantidadDigitos ( num / 10 ) ;
  19. }
  20.  
  21. int obtenerNumMinimo ( int digitos ) {
  22.   return ( digitos == 0 ) ? 1 : 10 * obtenerNumMinimo ( - 1 + digitos ) ;
  23. }
  24.  
  25. int obtenerNumMaximo ( int digitos ) {
  26.   return ( digitos == 0 ) ? 1 : 10 * obtenerNumMinimo ( - 1 + digitos ) ;
  27. }
  28.  
  29. void inicializar_digitosNumero ( int digitosNumero [ 10 ] , int indice ) {
  30.   if ( indice < 10 )
  31.     digitosNumero [ indice ] = 0 , inicializar_digitosNumero ( digitosNumero , indice + 1 ) ;
  32. }
  33.  
  34. int DigitosNumero ( int digitosNumero [ 10 ], int numero , int flag ) {
  35.   if ( numero > 0 && flag == 0 )
  36.     digitosNumero [ numero % 10 ]++ , DigitosNumero ( digitosNumero , numero / 10 , 0 ) ;
  37.   else if ( numero > 0 && flag == 1 )
  38.     digitosNumero [ numero % 10 ]-- , DigitosNumero ( digitosNumero , numero / 10 , 1 ) ;
  39.   if ( digitosNumero [ numero % 10 ] < 0 )
  40.     return  0 ;
  41.   else return 1 ;
  42. }
  43.  
  44. int ComprobarDigitos ( int digitosNumero [ 10 ] , int indice , int cont ) {
  45.   if ( indice < 10 )
  46.     if ( digitosNumero [ indice ] == 0 )
  47.       return 1 + ComprobarDigitos ( digitosNumero , indice + 1 , cont + 1 ) ;
  48.     else return
  49.       ComprobarDigitos ( digitosNumero , indice + 1 , cont  ) ;
  50.   return 0 ;
  51. }
  52.  
  53. int esVampiro ( int numero ) {
  54.   int  i , indice = 0 , n_maximo , n_minimo , numero_0 , numero_1 , digitos , digitosNumero [ 10 ] ;
  55.   inicializar_digitosNumero ( digitosNumero , indice ) ;
  56.   DigitosNumero ( digitosNumero , numero , 0 ) ;
  57.   digitos = cantidadDigitos ( numero ) ;
  58.   if ( digitos %2 != 0 )
  59.     return puts ( "\n\n\tNO ES VAMPIRO por numero impar de cifras.\n\n" ) , 0 ;
  60.   n_minimo = obtenerNumMinimo ( - 1 + digitos / 2 ) ;
  61.   n_maximo = obtenerNumMaximo ( digitos / 2 ) ;
  62.   numero_0 = numero_1 = n_minimo ;
  63.   return probar ( numero , numero_1 , numero_0 , n_minimo , n_maximo , digitos , digitosNumero ) ;
  64. }
  65.  
  66.  int probar ( int numero , int num_1 , int num_0 , int n_minimo , int n_maximo , int digitos , int digitosNumero [ 10 ]  ) {
  67.   int  i , indice = 0 ;
  68.   static int flag = 0  ;
  69.   if ( num_1 < n_maximo - 1 && num_0 == n_maximo )
  70.     num_0 = n_minimo , num_1 = numero / n_maximo  ;
  71.   if ( num_0 == n_maximo - 1 && flag == 0 )
  72.     return printf ( "\n\n\t%d NO ES VAMPIRO   flag = %d\n\n"  , numero , flag ) , 0 ;
  73.   if ( num_0 == n_maximo - 1 && flag > 0 )
  74.     return printf ( "\n\n\t%d ES VAMPIRO\n\n"  , numero ) , 1 ;
  75.   if ( num_0 < n_maximo ){
  76.     num_1 = numero / num_0  ;
  77.     if ( num_0 * num_1 == numero  && num_0 > num_1 ) {
  78.     inicializar_digitosNumero ( digitosNumero , 0  ) ;
  79.     DigitosNumero ( digitosNumero , numero , 0 ) ;
  80.     if ( num_0 * num_1 == numero  ) {
  81.       DigitosNumero ( digitosNumero , num_0 , 1 ) ;
  82.       DigitosNumero ( digitosNumero , num_1 , 1 ) ;
  83.       if ( ComprobarDigitos ( digitosNumero , 0 , 0 ) == 10 && ( num_0 % 10 != 0 ||  num_1 % 10 != 0 ) )
  84.         printf ( "\n\n\t%d = %d * %d\n\n" , numero , num_1 , num_0 ) , flag ++ ;
  85.     }
  86.   }
  87.   return  probar ( numero , num_1  , 1 + num_0 , n_minimo , n_maximo , digitos , digitosNumero )  ;
  88.  }
  89. }

Ejemplo de la salida:

Código C++:
Ver original
  1. 13078260 = 2070 * 6318
  2.  
  3. 13078260 = 1863 * 7020
  4.  
  5. 13078260 = 1620 * 8073
  6.  
  7. 13078260 ES VAMPIRO

¡¡¡Saluditos!!!