Ver Mensaje Individual
  #98 (permalink)  
Antiguo 09/12/2014, 00:53
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Petando la pila. Problemas y retos usando recursividad.

Como no quiero que me pase como con el de los números vampiros, aquí está mi primera propuesta para el ejercicio de ordenar:

Código C:
Ver original
  1. #define NUEVO_NODO(nodo,valor,padre)\
  2.   nodo = &padre->memoria->datos[ padre->memoria->nextIndex++ ]; \
  3.   nodo->ant = 0; nodo->sig = 0; \
  4.   nodo->repeticiones = 1; nodo->valor = valor; \
  5.   nodo->memoria = padre->memoria
  6.  
  7. struct Memoria;
  8.  
  9. struct Nodo
  10. {
  11.   int valor;
  12.   int repeticiones;
  13.  
  14.   struct Nodo* ant;
  15.   struct Nodo* sig;
  16.  
  17.   struct Memoria* memoria;
  18. };
  19.  
  20. struct Memoria
  21. {
  22.   struct Nodo* datos;
  23.   int nextIndex;
  24. };
  25.  
  26. void BuscarValor( struct Nodo* nodo, int valor )
  27. {
  28.   if ( nodo->valor < valor )
  29.   {
  30.     if ( nodo->sig == 0 )
  31.     {
  32.       NUEVO_NODO( nodo->sig, valor, nodo );
  33.     }
  34.     else
  35.     {
  36.       BuscarValor( nodo->sig, valor );
  37.     }
  38.   }
  39.   else if ( nodo->valor > valor )
  40.   {
  41.     if ( nodo->ant == 0 )
  42.     {
  43.       NUEVO_NODO( nodo->ant, valor, nodo );
  44.     }
  45.     else
  46.     {
  47.       BuscarValor( nodo->ant, valor );
  48.     }
  49.   }
  50.   else
  51.     ++nodo->repeticiones;
  52. }
  53.  
  54. void CrearArbol( struct Nodo* nodo, int* array, int longitud )
  55. {
  56.   BuscarValor( nodo, *array );
  57.  
  58.   if ( --longitud )
  59.     CrearArbol( nodo, ++array, longitud );
  60. }
  61.  
  62. void RegenerarArray( int* array, struct Nodo* nodo, int *pos )
  63. {
  64.   if ( nodo->ant )
  65.   {
  66.     RegenerarArray( array, nodo->ant, pos );
  67.     nodo->ant = 0;
  68.   }
  69.  
  70.   if ( nodo->repeticiones )
  71.   {
  72.     array[ (*pos)++ ] = nodo->valor;
  73.     if ( --nodo->repeticiones )
  74.       RegenerarArray( array, nodo, pos );
  75.   }
  76.  
  77.   if ( nodo->sig )
  78.   {
  79.     RegenerarArray( array, nodo->sig, pos );
  80.     nodo->sig = 0;
  81.   }
  82. }
  83.  
  84. void ordena(int array[], int n )
  85. {
  86.   Memoria memoria;
  87.   memoria.datos = (struct Nodo*)malloc( n * sizeof( struct Nodo ) );
  88.   memoria.nextIndex = 1;
  89.  
  90.   struct Nodo* root = memoria.datos;
  91.   root->valor = array[ 0 ];
  92.   root->repeticiones = 1;
  93.   root->sig = 0;
  94.   root->ant = 0;
  95.   root->memoria = &memoria;
  96.  
  97.   CrearArbol( root, &array[ 1 ], n-1 );
  98.  
  99.   int pos = 0;
  100.   RegenerarArray( array, root, &pos );
  101.  
  102.   free( memoria.datos );
  103. }

-------

EDITO: Bueno, ya puestos pongo también una primera aproximación al segundo ejercicio:

Código C:
Ver original
  1. #define IMPRIMIR( base, exponente, primerPrimo ) \
  2.   if ( primerPrimo == 0 ) printf( " *" ); \
  3.   if ( exponente == 1 ) printf( " %d", base ); \
  4.   else if ( exponente > 0 ) printf( " %d^%d", base, exponente )
  5.  
  6. int ComprobarPrimo( int* numero, int candidato )
  7. {
  8.   if ( *numero % candidato == 0 )
  9.   {
  10.     *numero /= candidato;
  11.     return 1 + ComprobarPrimo( numero, candidato );
  12.   }
  13.   return 0;
  14. }
  15.  
  16. void bucleChequeo( int numero, int candidato, int primerPrimo, int ver )
  17. {
  18.   int exp = ComprobarPrimo( &numero, candidato );
  19.   if ( exp > 0 && ver)
  20.   {
  21.     IMPRIMIR( candidato, exp, primerPrimo );
  22.     primerPrimo = 0;
  23.   }
  24.  
  25.   candidato += 2;
  26.   if ( numero > 1 )
  27.     bucleChequeo( numero, candidato, primerPrimo, ver );
  28. }
  29.  
  30. void descompon(int a, int b, int ver)
  31. {
  32.   int actual = a;
  33.   int exp = ComprobarPrimo( &actual, 2 );
  34.   if ( ver )
  35.   {
  36.     printf( "%d =", a );
  37.     IMPRIMIR( 2, exp, 1 );
  38.   }
  39.  
  40.   bucleChequeo( actual, 3, exp == 0, ver );
  41.  
  42.   if ( ver )
  43.     printf ( "\n" );
  44.  
  45.   if ( a < b )
  46.     descompon( ++a, b, ver );
  47. }
Un saludo.

Última edición por eferion; 09/12/2014 a las 02:50