Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: jamatbar en 12 Noviembre 2011, 14:26 pm



Título: Calculo de números primos
Publicado por: jamatbar en 12 Noviembre 2011, 14:26 pm
Me han dado el siguiente código de programa en c, es un programa que pide un numero por teclado e indica si el número es o no primo, comprobando todos los posibles divisores:



Código
  1. #include <stdio.h>
  2. int main()
  3. {
  4.  
  5. int valor;
  6.  
  7. int i;
  8.  
  9. printf("Introduzca un valor: ");
  10. scanf(" %d", &valor);
  11.  
  12. for ( i = 2; i < valor; i++ )
  13. if (0 == (valor % i))
  14.  
  15. printf(" %d no es primo\n", valor);
  16. return 0;
  17. }

He probado el código y es un poco malo, si el número es primo directamente se sale del programa, y si el número no lo es, te lo repite por cada divisor que tenga, y me han pedido que haga que solo se imprima un mensaje indicando si el número es primo o no al final del bucle. Para esto, nos dicen que utilicemos una variable de control, cuando encuentre un divisor se active dicha variable. Y al final del bucle se mostrará el mensaje adecuado segun el valor de la variable de control.

He pensado que se tendría que usar la variable de control flag, pero no sé como implementarla muy bien, ¿alguien podría aclararmelo?, yo lo he intentado poniendo esto:

Código
  1. #include <stdio.h>
  2. int main()
  3. {
  4.  
  5. int valor;
  6. int i;
  7. int flag;
  8. printf("Introduzca un valor: ");
  9. scanf(" %d", &valor);
  10.  
  11. flag=0;
  12.  
  13. for ( i = 2; i < valor; i++ )
  14. if (0 == (valor % i))
  15. {flag=1;
  16. printf(" %d no es primo\n", valor);
  17. }
  18. else
  19. flag=0;
  20. printf(" %d es primo\n", valor);
  21. return 0;
  22. }

Pero aun así, al probarlo me sigue dando error, ¿alguna solución?

Saludos


Título: Re: Calculo de números primos
Publicado por: DickGumshoe en 12 Noviembre 2011, 14:44 pm
No sé si te servirá, pero yo hice este programa hace tiempo (aunque en él no uso "for"):

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3.  
  4.  
  5.  
  6. int main(void)
  7. {
  8.  
  9. int num;
  10.  
  11. printf("\nIntroduce un numero");
  12. scanf("%d",&num);
  13.  
  14.  
  15. if((num%2==0) && (num!=2)){
  16.                     printf("El numero no es primo");}
  17. else{
  18.  
  19. if((num%3==0) && (num!=3)){
  20.                       printf("El numero no es primo");}
  21. else{
  22. if((num%5==0) && (num!=5)){
  23.  
  24.  
  25.                     printf("El numero no es primo");}
  26.       else{  
  27.  if((num%7==0) && (num!=7)){
  28.                        printf("El numero no es primo");}
  29.        else{
  30.  
  31. if((num%11==0) && (num!=11)){
  32.                       printf("El numero no es primo");}
  33. else{
  34.      printf("El numero es primo");
  35. }}}}}
  36.  
  37. system("pause");
  38.  
  39.  
  40.  
  41.  
  42.  
  43. }

Saludos.


Título: Re: Calculo de números primos
Publicado por: jamatbar en 12 Noviembre 2011, 14:52 pm
Gracias por la ayuda, aunque me piden que use una variable de control (flag), por eso no puedo ponerlo como tu lo tienes.

Saludos!


Título: Re: Calculo de números primos
Publicado por: $Edu$ en 12 Noviembre 2011, 15:02 pm
Ademas si usas el metodo de DickgumShoe y lo probarias con un numero muy grande tendrias que hacer miles de ifs mas xD para ahorrar esos ifs es que se usan los bucles DickgumShoe.

Y lo de la variable flag, le puedes llamar como quieras, solo sera una variable auxiliar pero veo que la declaras y le asignas valores pero nunca verificas el valor para hacer algo.. cosa que esta al pedo sino xD


Título: Re: Calculo de números primos
Publicado por: jamatbar en 12 Noviembre 2011, 15:19 pm
Ademas si usas el metodo de DickgumShoe y lo probarias con un numero muy grande tendrias que hacer miles de ifs mas xD para ahorrar esos ifs es que se usan los bucles DickgumShoe.

Y lo de la variable flag, le puedes llamar como quieras, solo sera una variable auxiliar pero veo que la declaras y le asignas valores pero nunca verificas el valor para hacer algo.. cosa que esta al pedo sino xD

EL problema es que no sé muy bien como usarla XD


Título: Re: Calculo de números primos
Publicado por: $Edu$ en 12 Noviembre 2011, 15:44 pm
Yo siempre recomiendo leer tranquilo un buen manual del lenguaje de programacion que quieren aprender, aprenderlo bien de bien, usar bucles bien de bien, saber muchas cosas y luego ahi si te vendra a la mente muchas posibles soluciones


Título: Re: Calculo de números primos
Publicado por: тαптяα en 12 Noviembre 2011, 15:55 pm
Aquí por si lo quereis primos, os dejo el codigo locos que escribe los primeros numeros primos, echadle un ojo.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define N 999
  4.  
  5. //Primo a pillar speed jajaja
  6.  
  7. int main ()
  8. {
  9.    int i, j, primo;
  10.    primo = 1;
  11.    for (i = 2; i < N; i++)
  12.    {
  13.       for ( j = 2; j <= i/2; j++)
  14.          if ((i%j) == 0)
  15.             primo = 0;
  16.       if(primo)
  17.          printf("%d\n", i);
  18.       primo = 1;
  19.    }
  20.    return 0;
  21. }


Título: Re: Calculo de números primos
Publicado por: $Edu$ en 12 Noviembre 2011, 16:05 pm
Ahi tenes tu variable flag jamatbar, es la que el uso como "primo" que tambien podes declararla como booleana para que le asignes True or False


Título: Re: Calculo de números primos
Publicado por: CobraCY en 12 Noviembre 2011, 16:10 pm
Bueno soy nuevo y se me dio echarle una mano.

Puedes hacerlo con un while o con un for, para el caso recomiendo el for, también puedes usar un flag int o bool, me gusta más el bool, pero bueno te dejo un ejemplo con el bool y otro con el int y también.

Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4. int main()
  5. {
  6. int n;
  7. cin >> n;
  8. int flag=0;
  9. for(int i=2; i < n && flag==0;i++)
  10. {
  11. if(n%i==0)
  12. flag++;
  13. }
  14.  
  15. if(flag==0 || n==1 || n==2)
  16. cout << "Es primo" << endl;
  17. else
  18. cout << "No es primo" << endl;
  19. return 0;
  20. }
  21.  
Este usa el flag en Int
Ahora uno que usa el Flag en bool
Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4. int main()
  5. {
  6. int n;
  7. cin >> n;
  8. bool flag=true;
  9. for(int i=2; i < n && flag;i++)
  10. {
  11. if(n%i==0)
  12. flag=false;
  13. }
  14.  
  15. if(flag || n==1 || n==2)
  16. cout << "Es primo" << endl;
  17. else
  18. cout << "No es primo" << endl;
  19. return 0;
  20. }
  21.  
Este usa el flag en Bool, como ves solo cambian, mmm en realidad no cambia nada xD. :)

Saludos.


Título: Re: Calculo de números primos
Publicado por: jamatbar en 12 Noviembre 2011, 16:40 pm
Vale, leyendo más o menos lo que habeís puesto he hecho lo siguiente:

Código
  1. #include <stdio.h>
  2. int main()
  3. {
  4.  
  5. int valor;
  6.  
  7. int i;
  8. int flag;
  9.  
  10. printf("Introduzca un valor: ");
  11. scanf(" %d", &valor);
  12.  
  13. for ( i = 2; i < valor; i++ )
  14. if (0 == (valor % i))
  15. flag=0;
  16. if (flag)
  17. printf("%d es primo\n",valor);
  18. flag=1;
  19.  
  20.  
  21. return 0;
  22. }

Si meto un número primo me dice que es primo (sólo con una sentencia),¿que puedo hacer para poner una función si el numero que meto es no primo?

Además, me he dado cuenta de que si meto un 1,2 o 3 el programa sale directamente, ¿por qué?
Saludos


Título: Re: Calculo de números primos
Publicado por: Ferno en 12 Noviembre 2011, 17:09 pm
Si ponés un 1 o un 2 en tu programa, no entra ni siquiera una vez en el for, porque no se cumple la condición (i < valor), ya que i comienza en el número 2.
Sin embargo, no está bien el algoritmo. Ese bucle no hace nada. ¿Como sabés si es primo o no ahí?
Primero pensá el problema matemáticamente, luego pasalo a la máquina tal cual lo pienses.
En este caso, un número es primo si y solo si es divisible sólo por si mismo y por el 1.
Entonces, para pasarlo a máquina, tendrás que ver si el número es divisible por algún número entre el 1 y el mismo. Para eso se usa el bucle, cuando encuentres algún número que divida a tu valor, entonces no será primo (ahí entra el flag en funcionamiento), sino, es primo.


Título: Re: Calculo de números primos
Publicado por: jamatbar en 12 Noviembre 2011, 17:18 pm
Perdon, me comí un par de líneas de código, ya lo he editado

Saludos


Título: Re: Calculo de números primos
Publicado por: rir3760 en 12 Noviembre 2011, 17:33 pm
En el caso de la aproximacion de fuerza bruta esta se puede mejorar un poco reduciendo el rango y utilizando al contador del bucle como bandera. De esta forma:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int es_primo(int num);
  5.  
  6. int main(void)
  7. {
  8.    int i;
  9.  
  10.    for (i = 2; i < 100; i++)
  11.        if (es_primo(i))
  12.            printf("%d\n", i);
  13.  
  14.    return EXIT_SUCCESS;
  15. }
  16.  
  17. int es_primo(int num)
  18. {
  19.    int i;
  20.  
  21.    for (i = 2; i*i <= num && num % i != 0; i++)
  22.        ;
  23.  
  24.    return i*i > num;
  25. }

Un saludo


Título: Re: Calculo de números primos
Publicado por: jamatbar en 12 Noviembre 2011, 17:48 pm
Ya he conseguido hacerlo, muchas gracias a todos por vuestra ayuda.

Saludos!


Título: Re: Calculo de números primos
Publicado por: jamatbar en 12 Noviembre 2011, 18:03 pm
A ver, el programa me ha quedado así:

Código
  1. #include <stdio.h>
  2.  
  3. int main ()
  4. {
  5.  int valor;
  6.  int i;
  7.  int flag = 1;//variable de control
  8.  printf("Introduzca un valor:");
  9.  scanf ("%d", &valor);//lee el número
  10.  
  11.  for (i=2; i < valor ; i++ )
  12.    if (0 == (valor % i ))
  13.      {//bucle que se repite hasta que i es igual a valor
  14. flag = 0;
  15.      }
  16.  if (flag == 1)
  17.    printf ("%d es un número primo\n", valor);
  18.  else // en funcion del valor de flag se imprime una u otra cosa
  19.    printf ("%d no es primo \n", valor);
  20.  return 0;
  21. }

Ahora me piden que: Para mejorar la eficiencia del programa, el bucle debe finalizar una vez encontrado el primer divisor. Para ello deberá hacer uso de la variable de control usada en el apartado anterior.

No lo entiendo, ¿se supone que el programa ya termina cuando encuentra un divisor no?

Saludos


Título: Re: Calculo de números primos
Publicado por: Ferno en 12 Noviembre 2011, 18:14 pm
Te recomiendo enormemente ponerle respectivas llaves a todas las instrucciones, más allá de que lleven una sola sentencia o no.
Ahora bien, no, ahí el programa sigue hasta terminar con el bucle for.

Para que termine cuando el flag lo indique o cuando llegue a terminar todas las repeticiones deberás usar otra estructura repetitiva (while o do-while) con 2 condiciones: Que el flag siga siendo falso y hasta que llegue al valor en cuestión.


Título: Re: Calculo de números primos
Publicado por: CobraCY en 12 Noviembre 2011, 18:15 pm
ya mira, cuando haces el FOR, dices: "Declara una variable 'i' que inicie en dos(2) y que se aumente en 1(i++) mientras que sea menor a el valor de 'n'.".

Con esto haces que tu variable 'i' haga el recorrido desde el numero 2 hasta n.
Si vez bien el código que te puse usé la siguiente linea para el FOR:
Código
  1. for(int i=2; i < n && flag==0;i++)
  2.  

Con esto digo: "Declara una variable 'i' que inicie en dos(2) y que se aumente en 1(i++) mientras que mi variable 'i' sea menor que 'n' y además que mi variable 'flag' sea sea exactamente igual a cero(0)".

Si te das cuenta en tu código haces un 'if' donde preguntas si el residuo de tu valor entre el valor que lleva la variable 'i' es cero(0), entonces cambie tu flag a 0, ese valor puedes utilizarlo en el for para que si 'flag' es distinto(!=) de cero(0) entonces continúe con la ejecución del for.

Saludos.


Título: Re: Calculo de números primos
Publicado por: RyogiShiki en 12 Noviembre 2011, 18:26 pm
NO he visto las respuestas, pero dejo este video que ayuda mucho:

http://www.youtube.com/watch?feature=player_embedded&v=FU1hi6cSpjQ


Título: Re: Calculo de números primos
Publicado por: satu en 12 Noviembre 2011, 20:24 pm
Hola

Además el bucle se podría acortar hasta la mitad:

Código
  1. for(int i=2; i <= n/2 && flag==0;i++)
  2.  

Saludos


Título: Re: Calculo de números primos
Publicado por: CobraCY en 12 Noviembre 2011, 21:13 pm
te hice un video rápido para ver si te puedo ayudar.
t3zY9IXOxzU
Saludos.


Título: Re: Calculo de números primos
Publicado por: s00rk en 12 Noviembre 2011, 23:59 pm
No se puede utilizar dentro del if el break; y ya ? xD
Terminara el for y continuara  :silbar:


Título: Re: Calculo de números primos
Publicado por: CobraCY en 13 Noviembre 2011, 00:22 am
si, pero el está pidieron que utilicemos un flag. Así que hay que cumplir con sus exigencias xD.

Saludos.


Título: Re: Calculo de números primos
Publicado por: jamatbar en 13 Noviembre 2011, 22:47 pm
Gracias a todos por vuestras ayudas, y hombre, no son exigencias, es que básicamente me lo piden con eso XD


Título: Re: Calculo de números primos
Publicado por: jamatbar en 13 Noviembre 2011, 23:14 pm
Mi código ha quedado así:

Código
  1. #include <stdio.h>
  2. int main()
  3. {
  4. int valor;
  5. int i;
  6. int flag = 1;
  7.  
  8. printf("Introduzca un valor: ");
  9. scanf(" %d", &valor);
  10.  
  11. for ( i = 2; i < valor && flag!=0; i++ )
  12. if (0 == (valor % i))
  13. {flag = 0;
  14. }
  15. if (flag == 1)
  16. printf(" %d es primo\n", valor);
  17. else
  18. printf(" %d no es primo\n",valor);
  19. return 0;
  20. }
  21.  

Pero ahora me piden que una vez comprobado que el dos no es divisor, probar sólo con los números impares.


EDITO poniendo lo que he intentado:

Código
  1. #include <stdio.h>
  2. int main()
  3. {
  4. int valor;
  5. int i;
  6. int flag = 1;
  7.  
  8. printf("Introduzca un valor: ");
  9. scanf(" %d", &valor);
  10.  
  11. for ( i = 2; i < valor && flag!=0; i+=2 )
  12. if (0 == (valor % i))
  13. {flag = 0;
  14. }
  15. if (flag == 1)
  16. printf(" %d es primo\n", valor);
  17. else
  18. printf(" %d no es primo\n",valor);
  19. return 0;
  20. }
  21.  

¿Con eso bastaría no?


Saludos


Título: Re: Calculo de números primos
Publicado por: rir3760 en 14 Noviembre 2011, 02:17 am
No porque si revisas el bucle te daras cuenta que solo estas dividiendo entre los numeros pares mientras que el enunciado te pide revisar la serie 2, 3, 5, 7, ... N.

Un problema con el (debido a esa serie) es que debes manejar el caso especial donde el numero es par, si es dos es primo, cualquier otro no lo es.

Con los cambios:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void)
  5. {
  6.    int numero;
  7.    int i;
  8.    int es_primo;
  9.  
  10.    printf("Introduce el numero: ");
  11.    fflush(stdout);
  12.    if (scanf("%d", &numero) != 1 || numero < 2)
  13.        return EXIT_FAILURE;
  14.  
  15.    es_primo = numero == 2 || numero % 2 == 1;
  16.    for (i = 3; i < numero && es_primo; i += 2)
  17.        if (numero % i == 0)
  18.            es_primo = 0;
  19.  
  20.    if (es_primo)
  21.        printf("%d es primo\n", numero);
  22.    else
  23.        printf("%d no es primo\n", numero);
  24.  
  25.   return EXIT_SUCCESS;
  26. }

Un saludo


Título: Re: Calculo de números primos
Publicado por: xBurninGx en 14 Noviembre 2011, 03:09 am
Hola,

si nos ponemos a hacer código, cuando mejor sea mejor, no?

para saber si es un número es primo, no hay que llegar a dividirle entre todos los numeros anteriores a ese número para saberlo, por una demostración algebraica, que no me voy a para a explicar, con probar hasta la raíz cuadrada de ese mismo número es suficiente (raíz cuadrada inclusive, así que hace falta sustituir el menor por un menor o igual en el for).

ahora, para saber la raíz cuadrada de un número hace falta importar la biblioteca math.h, además de tener en cuenta al compilar, poner la opción "-lm", con lo que un ejemplo de compilación puede ser:

gcc -lm -o prueba prueba.c

y el programa quedaría de la siguiente manera:



Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. int main(void)
  6. {
  7.   int numero;
  8.   int i;
  9.   int es_primo;
  10.  
  11.   printf("Introduce el numero: ");
  12.   fflush(stdout);
  13.   if (scanf("%d", &numero) != 1 || numero < 2)
  14.       return EXIT_FAILURE;
  15.  
  16.   es_primo = numero == 2 || numero % 2 == 1;
  17.   for (i = 3; i <= sqrt(numero) && es_primo; i += 2)
  18.       if (numero % i == 0)
  19.           es_primo = 0;
  20.  
  21.    printf("%d %s primo\n", numero, (es_primo)?"es":"no es");
  22.  
  23.  return EXIT_SUCCESS;
  24. }
  25.  
  26.  

Saludos


Título: Re: Calculo de números primos
Publicado por: do-while en 14 Noviembre 2011, 09:06 am
¡Buenas!

Puestos a liarla:
Código
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5.    int numero;
  6.    int i;
  7.    int es_primo;
  8.  
  9.    printf("Introduce el numero: ");
  10.    fflush(stdout);
  11.  
  12.    while(!scanf("%d", &numero))
  13.        while(getchar() != '\n');
  14.  
  15.    for (es_primo = (numero > 1 && (numero == 2 || numero % 2 == 1)) , i = 2 ; i * i <= numero && (es_primo = (numero % i != 0)); i++);
  16.  
  17.    printf("%d %s primo\n", numero, es_primo ? "es" : "no es");
  18.  
  19.    return 0;
  20. }
  21.  

XD

¡Saludos!


Título: Re: Calculo de números primos
Publicado por: rir3760 en 14 Noviembre 2011, 23:33 pm
Hay que tener cuidado al utilizar el valor de retorno de scanf:
Código
  1. while(!scanf("%d", &numero))
  2.   while(getchar() != '\n');
En caso de error o fin de archivo la funcion retorna EOF, eso causaria la salida del bucle con el valor de la variable "numero" como (todavia) "no definido" o "basura".

Un saludo