Ya vimos como calcular el factorial de un número c++ en forma recursiva, sin embargo hay una forma mucho mas fácil de entender y de aplicar (pero menos eficiente). Vamos viendo:
Si el factorial de un número es la multiplicación de cada número desde 1 hasta ese número (por ejemplo factorial de 4 = 1*2*3*4 = 24), entonces es muy sencillo crear un ciclo de 1 hasta el número pedido en c++ para hacer el cálculo.
#include<iostream>
using namespace std;
int main()
{
int num,fact=1;
cout << "::FACTORIAL::" << endl;
cout << "Introduce un numero: "; cin >> num;
for(int i=2; i<=num; i++)
{
fact = fact * i;
}
cout << "Su factorial es: " << fact;
cin.get();cin.get();
return 0;
}
¿Entonces porqué el ciclo empieza en 2? Si comenzara en 1, el proceso para el numero 3 (por poner un ejemplo) serÃa asÃ:
- fact = fact * i -> fact = 1 * 1 -> fact = 1
- fact = fact * i -> fact = 1 * 2 -> fact = 2
- fact = fact * i -> fact = 2 * 3 -> fact = 6
Como ven, el primer paso es totalmente innecesario.
Este juego matemático es clásico de los problemas de programación. Hoy vamos a ver cómo calcular el número de movimientos necesarios para resolver el juego según el número de discos, de forma recursiva en C++.
#include<stdio.h>
int hanoi(int n)
{
if(n==1)
return 1;
else
return 2 * hanoi(n-1) + 1;
}
int main()
{
int disc, mov;
printf("::TORRES DE HANOI::\n");
printf("Numero de discos: ");scanf("%i",&disc);
printf("\tMovimientos necesarios: %i\n", hanoi(disc));
return 0;
}
Otro algoritmo raro. Lo que sabemos es que si tenemos 1 disco el número de movimientos es 1 y que ese es nuestro caso base (si n==1 retorna 1), a partir de ahà el número de movimientos se puede calcular si multiplicamos por dos el número de movimientos para n-1 y le sumamos 1, o sea: 2 + hanoi(n-1) + 1
- Si son 2 discos, entonces 2 * hanoi(1) + 1 = 2 * 1 + 1 = 3
- Si son 3 discos, entonces 2 * hanoi(2) + 1 = 2 * 3 + 1 = 7
- etc
Ooootro post sobre recursividad, pero no se preocupen ya solo queda este y otro. Esta vez vamos a calcular el máximo común divisor de dos números de forma recursiva en c++.
#include<stdio.h>
int MCD(int x, int y)
{
if(y==0)
return x;
else
return MCD(y, x%y);
}
int main()
{
int num1=0,num2=0;
printf("::MAXIMO COMUN DIVISOR::\n");
printf("Introduce el primer numero: ");scanf("%i",&num1);
printf("Introduce el segundo numero: ");scanf("%i",&num2);
printf("\tEl resultado es: %i\n", MCD(num1, num2));
return 0;
}
Este es uno de esos algoritmos recursivos raros o, mejor dicho, difÃciles de comprender, mi cerebro estuvo un buen rato echando humo tratando de comprender la lógica con que lo armaron y mi conclusión es que funciona de pura rana. Bueno, al final si supe como funciona pero no porque.
0, 1, 1, 2, 3, 5, 8, 13, 21, …, la serie de Fibonacci es bastante interesante e incluso aparece en la naturaleza. Comienza con un 0, luego un 1 y a partir de ahà cada número es la suma de los dos siguientes. Eso último nos indica recursividad. Veamos como mostrar n números de la serie de Fibonacci de forma recursiva en C++.
#include<stdio.h>
int fibonacci(int n)
{
if (n<2)
return n;
else
return fibonacci(n-1) + fibonacci(n-2);
}
int main()
{
int num=0,res=0;
printf("::NUMEROS DE FIBONACCI::\n");
printf("Introduce el numero de numeros: ");scanf("%i",&num);
printf("\t");
for(int i=0;i<=num-1;i++)
{
res = fibonacci(i);
printf("%i ", res);
}
printf("\n");
return 0;
}
Es la primera vez que vemos un la llamada a la función dentro de un ciclo. Eso es porque la función calcula el n-ésimo número de la serie, y para mostrarlos todos tenemos que hacer un ciclo que repita la función tantas veces como sea necesario.
Siguiendo con esto de la recursividad hoy les traigo un nuevo programÃn, Convertir Decimal a Binario de forma recursiva.
#include<stdio.h>
void binario(int n)
{
if (n!=0)
{
binario(n/2);
printf("%i",n%2);
}
}
int main()
{
int num=0;
printf("::CONVERTIR DECIMAL A BINARIO::\n");
printf("Introduce un numero: ");scanf("%i",&num); //Pedir variable num
printf("\t");binario(num);printf("\n"); //Llamar la función
return 0;
}
Está basado en el método que usamos para convertir un número decimal a binario “a mano”: dividir el número entre dos hasta que quede 0 y apuntar los residuos del último al primero.
Hola de nuevo, ¿cuánto tiempo pasó? mmm no sé pero bueno… lo importante es que ya estoy de vuelta y ahora sà me voy a dar el tiempo de actualizar este blog más seguido, pero basta de cosas personales.
No me quiero meter en rollos de explicar lo que es la recursividad (googleen y diviértanse leyendo), lo que quiero es mostrarles algunos ejemplos muy sencillos de dónde podemos aplicar la recursividad. Hoy toca calcular el factorial de un numero de forma recursiva.
Es el código recursivo más fácil que se pueden encontrar:
#include<stdio.h>
int factorial(int n)
{
if(n<2)
return 1;
else
return n * factorial(n-1);
}
int main()
{
int num=0;
printf("::CALCULAR FACTORIAL::\n");
printf("Introduce un numero: ");scanf("%i",&num); //Pedir variable num
printf("\tEl resultado es: %i\n", factorial(num)); //Llama la funcion e imprime resultado
return 0;
}
Explicación
El caso base es que cuando n valga 1 o 0 retorna un 1, de lo contrario retorna la multiplicación de n * el factorial del numero anterior n-1. Supongamos que introducimos el número 3, cuyo factorial es 6 (3*2*1 = 6).
- n=3 No entra al caso base. Guardamos para después la operación 3 * factorial(2)
- n=2 No entra al caso base. Guardamos para después la operación 2 * factorial(1)
- n=1 Entra al caso base. Retorna 1, por lo tanto factorial(1) = 1
- Hacemos la última operación que guardamos 2 * factorial(1) = 2 * 1 = 2, por lo tanto factorial(2) = 2
- Hacemos la siguiente operación que guardamos 3 * factorial(2) = 3 * 2 = 6
- El factorial es 6
¡Uh que fácil!
Guardado en: TeorÃa el 25 de noviembre del 2009
Etiquetas: rand
Es algo muy frecuente, cuando ya dominas todo eso de pedir y almacenar datos, ahora tu profesor te pedirá que tus programas generen números aleatorios para automatizar el proceso de llenar arreglos y todo eso.
Asà que lo primero que tenemos que hacer es incluir la librerÃa:
#include<stdlib.h>
Luego inicializar los números aleatorios incluyendo esto:
srand(time(NULL));
*Actualización: No se porqué con algunos IDE’s tira error con la función time. Solo hay que utilizar además la librerÃa time.h:
#include<time.h>
Luego guardar el número aleatorio en alguna parte:
num=rand();
Eso es básicamente. Para ajustar el rango de número aleatorios podemos hacer varias cosas.
Número aleatorios entre 0 y 50:
num=rand()%51;
Número aleatorios entre 1 y 100:
num=1+rand()%(101-1);
Número aleatorios entre 250 y 420:
num=250+rand()%(421-250);
De forma general es:
variable = limite_inferior + rand() % (limite_superior +1 - limite_inferior) ;
Asà que un programa que muestre 10 números aleatorios entre 1 y 10 quedarÃa asÃ:
#include<stdlib.h>
#include<iostream>
using namespace std;
int main()
{
int num,c;
srand(time(NULL));
for(c=1;c<=10;c++)
{
num=1+rand()%(11-1);
cout<<num<<" ";
}
cin.get();
}
Bueno, tal vez el tÃtulo quedó muy poco descriptivo, pero la idea es pedir un número de personas, luego se le pedirÃa a cada persona su peso pero nosotros solo vamos a generar un número aleatorio en determinado rango. Luego se clasificarÃa a esas personas en rangos de peso y al final mostrar una tabla que muestre la frecuencia de cada rango con asteriscos, asÃ:
51-60 ***
61-70 **
71-80 ***
80-91 *
91-mas *****
El código en C++ serÃa asÃ:
#include<stdlib.h>
#include<iostream>
using namespace std;
int main()
{
int n,c,c2,peso[500],cat[5]={0},lim;
// n -> numero de personas
// c y c2 para ciclos
// peso[500] arreglo para guardar el peso de las personas
// cat[5] arreglo para guardar el número de personas en cada categoria de peso
srand(time(NULL)); // Inicializa los números aleatorios
cout<<"Introduce el número de personas: ";cin>>n;
for(c=0;c<=n-1;c++)
{
peso[c]=51+rand()%(120-51); //guarda un número aleatorio del 51 al 120 en cada elemento del arreglo
// según su valor se aumenta un elemento de nuestro otro arreglo
if(peso[c]>50 && peso[c]<=60)
cat[0]++;
if(peso[c]>60 && peso[c]<=70)
cat[1]++;
if(peso[c]>70 && peso[c]<=80)
cat[2]++;
if(peso[c]>80 && peso[c]<=90)
cat[3]++;
if(peso[c]>90)
cat[4]++;
}
cout<<"\n";
for(c=0;c<=4;c++)
{
switch(c)
{
// segun cada caso imprime algo diferente
case 0:
cout<<"51-60\t";
break;
case 1:
cout<<"61-70\t";
break;
case 2:
cout<<"71-80\t";
break;
case 3:
cout<<"81-90\t";
break;
case 4:
cout<<"90- \t";
break;
}
lim=cat[c]; // no podemos usar un arreglo como limite del ciclo (la verdad
// no se porque), entonces lo pasamos a una variable normal
for(c2=1;c2<=lim;c2++)
cout<<"*";
cout<<"\n\n";
}
cin.get();cin.get(); // detiene la ejecución al final (es como getch();)
}
A propósito, este programa fue una petición especial de un usuario.