• Domingo 15 de Diciembre de 2024, 00:47

Autor Tema:  Numeros perfectos  (Leído 3450 veces)

SkullFlower

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Numeros perfectos
« en: Miércoles 20 de Enero de 2010, 04:02 »
0
Hola,

quiero hacer un programa que le introduzcan cuantos numeros perfectos quiere que el programa saque por ejemplo si pones un 1 pues va a imprimir solo el primer numero perfecto y si pones 2 pues los primeros 2 numeros perfectos y asi sucesivamente.

Mi problema es que por ejemplo si pongo que calcule 1 saca el primer numero perfecto y sigue sacando los que siguen, tambien pasa lo mismo si pongo que calule 2 y con cualquier otro numero.

este es el codigo que tengo hasta ahorita:

Código: C
  1. #include<stdio.h>
  2. void perfecto(int x);
  3. int main(){
  4.     int y, x;
  5.     printf("Introduzca cuantos numeros perfectos quiere: ");
  6.     scanf("%d", &x);
  7.     while(x >= 1){
  8.         for(y = 1; ;y++){
  9.             perfecto(y);
  10.             x--;
  11.         }
  12.     }
  13.     return 0;
  14. }
  15.  
  16. void perfecto(int x){
  17.     int sum = 0, y;
  18.     for(y = 1; y < x/2+1; y++){
  19.         if(x % y == 0){
  20.             sum += y;
  21.         }
  22.     }
  23.     if(sum == x){
  24.         printf("%dn", x);
  25.     }
  26. }
  27.  

Aprendiz21Sam

  • Miembro activo
  • **
  • Mensajes: 32
    • Ver Perfil
Re: Numeros perfectos
« Respuesta #1 en: Miércoles 20 de Enero de 2010, 10:57 »
0
Vamos a analizar tu código.
Lo primero que veo es que tu procedimiento utiliza las variables "y", "x". Esto es muy peligroso a la hora de usarlas porque el mínimo descuido supone que el programa se ejecute de forma no deseada.

Código: C
  1. void perfecto(int x);
  2.  
(Esta es tu función, y le estás pasando "x").

Código: C#
  1. while(x >= 1){
  2.         for(y = 1; ;y++){
  3.             perfecto(y);
  4.             x--;
  5.         }
  6.     }
  7.  

Aquí estás pasando (y) y luego en el procedimiento la vuelves a definir. Aquí juegas con fuego porque te repites con las variables.


Esto son unas pistas, intenta solucionarlo y si no lo consigues escribe los nuevos problemas que tienes y te iré dando más pistas. Luego te pondré explícitamente en qué estás fallando pero ahora trata de ordenar tu programa para verlo todo mejor.

EI: juntando mensajes, usa el boton Modificar por favor.

Fíjate en este código. Como verás esta mas estructurado y tiene mayor facilidad de lectura. Este programa funciona perfectamente. Intenta averiguar cuáles son las diferencias y en qué te equivocaste. Si no lo encuentras vuelve a preguntar y te diré tus fallos, pero intenta pensarlo tú mismo.

Código: C
  1. /*Bibliotecas de C*/
  2. #include <stdio.h>
  3. #include <conio.h>
  4.  
  5. /*Declaración de mis funciones*/
  6. int es_perfecto (int N);
  7.  
  8. /*Programa principal*/
  9. int main()
  10. {
  11.     /*Declaración de las variables*/
  12.     int X;
  13.     int N;
  14.     int pares=0;
  15.    
  16.     /*Petición de datos*/
  17.     printf("Introduce el numero de numeros perfectos que quieres averiguar: ");
  18.     scanf ("%d", &X);
  19.    
  20.     /*Algoritmo principal*/
  21.     for(N=2; pares!=X; N++)
  22.     {
  23.       if(N%2==0 && es_perfecto(N))
  24.       {
  25.               printf("%d ", N);
  26.               pares++;
  27.        }
  28.     }
  29.     getch();
  30.     return 0;
  31. }
  32.  
  33. /*Realización de la función*/
  34. int es_perfecto (int N)
  35. {
  36.     int suma = 0;
  37.     int i;
  38.  
  39.     for(i=1; i<=(N/2); i++)
  40.        if(N%i==0)
  41.      suma += i;
  42.  
  43.     if(suma==N)
  44.       return 1;
  45.  
  46.     return 0; /* el "else" no hace falta */
  47. }
  48.  

SkullFlower

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Re: Numeros perfectos
« Respuesta #2 en: Miércoles 20 de Enero de 2010, 23:56 »
0
hola gracias por responder  :D

estaba viendo el codigo que pusiste y en la funcion:

Código: C
  1. int es_perfecto (int N)
  2. {
  3.     int suma = 0;
  4.     int i;
  5.  
  6.     for(i=1; i<=(N/2); i++)
  7.        if(N%i==0)
  8.      suma += i;
  9.  
  10.     if(suma==N)
  11.       return 1;
  12.  
  13.     return 0; /* el "else" no hace falta */
  14. }
  15.  

veo que no pones las llaves en los ifs ni en el for, es lo mismo si las pongo o no?

otra cosa:

Citar
Lo primero que veo es que tu procedimiento utiliza las variables "y", "x". Esto es muy peligroso a la hora de usarlas porque el mínimo descuido supone que el programa se ejecute de forma no deseada.

por que dices eso?

Aprendiz21Sam

  • Miembro activo
  • **
  • Mensajes: 32
    • Ver Perfil
Re: Numeros perfectos
« Respuesta #3 en: Jueves 21 de Enero de 2010, 10:48 »
0
Yo siempre pongo las llaves para verlo mejor. En este caso no las puse porque tenía un poco de prisa pero hay que ponerlas. El único momento donde no hace falta poner las llaves es cuando dentro de el "if" or de un bucle sólamente hay una instrucción.

Por ejemplo.

Código: C
  1. if (x > 3)
  2.   x = 2
  3.  

Código: C
  1. if (x > 3)
  2. {
  3.   x = 2
  4. }
  5.  

En este caso ambas están bien.





Código: C
  1. if (x > 3)
  2.   x = 2
  3.   suma = suma + x
  4.  

Código: C
  1. if (x > 3)
  2. {
  3.   x = 2
  4.   suma = suma + x
  5. }
  6.  

En este caso no significan lo mismo. Y si lo que quieres hacer es la segunda la primera estaría mal, porque dentro del if sólo entraría la primera instrucción "x = 2".


Lo de las variables digo que es peligroso por cuestiones de ámbito. Tú no estás haciendo un único algoritmo, sino que dentro de ese algoritmo estás utilizando funciones (que son subalgoritmos) y mezclar variables globales con variables locales, así como confundir los parámetros formales puede hacer que tu programa se vea afectado. Se pueden usar pero hay que tener cuidado.

Yo te recomiendo que crees tus propias variables dentro del subalgoritmo, y que las variables que pases a un subalgoritmos las nombres con "f_" delante del nombre.

Por ejemplo, si tienes una variable que se llama x (en el programa principal), y se la vas a pasar a una función, en la cabecera y en la implementación de la función pongas "f_x", osea (int subalgoritmo (f_x);) en vez de (int subalgoritmo (x);).

Espero que te sirva de ayuda.

SkullFlower

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Re: Numeros perfectos
« Respuesta #4 en: Viernes 22 de Enero de 2010, 02:40 »
0
Hola de nuevo.

Tratare de ya no usar las mismas variables para la proxima.

Batallo mucho haciendo ese tipo de programas y aveces mejor no los hago y ahora tengo que hacer un programa parecido pero con numeros primos.

si batallo mucho haciendo este tipo de programas significa que no sere buen programador? XD

otra cosa:

Código: C
  1. if(N%2==0 && es_perfecto(N))
  2.  

esa parte no la entendi muy bien, me la podrias explicar?

y por ultimo:

Usando tu codigo puse que calculara 5 numeros y los primeros los muestra y ya despues se queda asi y no muestra el quinto, segun wikipedia el numero que sigue es el 33550336. Sera que el programa todavia no llega a ese numero?(ya lleva como 10 ~ 15 min ejecutado).

Aprendiz21Sam

  • Miembro activo
  • **
  • Mensajes: 32
    • Ver Perfil
Re: Numeros perfectos
« Respuesta #5 en: Viernes 22 de Enero de 2010, 13:04 »
0
Con lo ultimo que dijiste, el 4º no lo calcula porque estas utilizando variables de tipo "int". Este tipo de variables no llega a números tan altos.

Con respecto a esa línea de código...

Código: C
  1. if(N%2==0 && es_perfecto(N))
  2.  

Esto quiere decir que, Si "N" es par, y perfecto, haremos lo que hay dentro. En C no existe el tipo "Booleano" pero utiliza para ello los de tipo "int". Si es "0" falso y en cualquier otro caso verdadero. Puedes consultarlo en algún manual pero creo recordar que era así. Bueno y esa línea de código es fundamental porque si no nunca veríamos los números perfectos que van saliendo.

SkullFlower

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Re: Numeros perfectos
« Respuesta #6 en: Viernes 22 de Enero de 2010, 21:52 »
0
mira ya hice el programa de los numeros primos modificando unas cuantas cosas del que pusiste para numeros perfectos  :P

Código: C
  1. #include<stdio.h>
  2. int primo(int Y_);
  3. main(){
  4.     int X;
  5.     int Y;
  6.     int Z = 0;
  7.     printf("Cuantos numeros primos desea calcular: ");
  8.     scanf("%d", &X);
  9.     for(Y = 1; Z != X; Y++){
  10.         if(primo(Y)){
  11.             printf("[%d] ", Y);
  12.             Z++;
  13.         }
  14.     }
  15.     while(getchar()!='n');
  16.     getchar();
  17.     return 0;
  18. }
  19. int primo(int Y_){
  20.     int X_;
  21.     int suma = 0;
  22.     for(X_ = 1; X_ <= Y_; X_++){
  23.         if(Y_ % X_ == 0){
  24.             suma++;
  25.         }
  26.     }
  27.     if(suma == 2){
  28.         return 1;
  29.     }
  30.     return 0;
  31. }
  32.  

y pues ya seria todo, Gracias por la ayuda  ^_^

Aprendiz21Sam

  • Miembro activo
  • **
  • Mensajes: 32
    • Ver Perfil
Re: Numeros perfectos
« Respuesta #7 en: Sábado 23 de Enero de 2010, 14:49 »
0
Muy bien, me encanta como has hecho el paso de parámetros además de que ahora si que le has puesto un nombre de variable distinto a la función. El código esta bastante bien estructurado. Yo lo único que le añadiría, pero no solo a éste sino a todos son los comentarios. Puedes hacerlos de dos tipos:

Comentarios de línea: Estos los pones para las líneas que no se entiendan mucho a simple vista. Explicas que hace.

Comentarios estructurados: Por ejemplo. /*Librerías de C*/ Y debajo pones las librerías que vayas a usar. Luego /*Cabecera de las funciones*/, etc. Esto es lo que se llama esqueleto de un programa. Para los ejercicios que tu haces el esqueleto te irá muy bien. De hecho puedes hacerte tu esqueleto y guardarlo en un documento, así cuando empieces un programa nuevo, pegas el esqueleto y empiezas el programa de una forma mas clara.

Buen trabajo.

EDITADO: Una cosa que si le añadiría además al programa es este bucle para evitar un bug.
   
Código: C
  1.  do
  2.     {
  3.       printf("nCuantos numeros primos desea calcular: ");
  4.       scanf("%d", &X);
  5.       if (X < 0);
  6.       printf ("nEl número debe ser mayor que cero, vuelva a introducir un número por favor");
  7.     }
  8.     while (X < 0);
  9.  

De esta forma, si alguien mete un número negativo no se te queda en un bucle infinito.

SkullFlower

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Re: Numeros perfectos
« Respuesta #8 en: Sábado 23 de Enero de 2010, 21:08 »
0
Gracias por el consejo, ya modifique el codigo pero otra cosa.

Como hacer lo mismo pero para cuando alguien introduzca una letra o un simbolo?

Aprendiz21Sam

  • Miembro activo
  • **
  • Mensajes: 32
    • Ver Perfil
Re: Numeros perfectos
« Respuesta #9 en: Martes 26 de Enero de 2010, 14:07 »
0
Creo que eso no es posible hacer con "scanf" debido a que el tipo de dato "%d" no puede ser una letra, por lo que no puedes evitar que te cuelen un carácter cuando quieran usando la función "scanf". Si alguien con más conocimientos sabe como hacerlo agradecería que lo pusiera pero creo que no se puede.