Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Ja_90 en 5 Septiembre 2014, 07:22 am



Título: Array con numeros primos.
Publicado por: Ja_90 en 5 Septiembre 2014, 07:22 am
Buenas Noches es mi primera vez en el foro, espero estar por acá un poco mas y ampliar mis conocimientos y apoyar y colaborar con los demás cuando este en capacidad y conozca de algún tema.  Quiero hacer un arreglo donde se visualicen los números primos del 1 al 100. Hice el siguiente código pero nada me imprime.
Alguna corrección o mejoría es bienvenida. gracias.

Código
  1. /* Escribir un programa que almacene en un arreglo los
  2.    números primos comprendidos entre 1 y 100. */
  3.  
  4. #include <iostream>
  5. #include <stdlib.h>
  6. using namespace std;
  7.  
  8. int main()
  9. {
  10.   int array_prime[100];
  11.   int z,x,num=1,add=0;
  12.  
  13.   for(x=0;x<100;x++)  // recorro y lleno el arreglo con los # del 1 al 100
  14.   {
  15.       array_prime[x]=num++;
  16.   }
  17.     for(x=0;x<100;x++) //Recorro el arreglo
  18.     {
  19.       for(z=1;z<=x;z++) // for para probar cada numero del arreglo es primo
  20.       {
  21.         if(x%z==0)add++;  // si el residuo es 0, contador add cuenta.
  22.       }
  23.       if(add==2)  // si el contador es igual a 2, el #del arreglo es primo.
  24.       {
  25.          cout<<array_prime[x]; //asigno el #primo al array. imprimo
  26.       }
  27.     }
  28.    cin.get();cin.get();
  29.    return 0;
  30. }
  31.  


Título: Re: Array con numeros primos.
Publicado por: eferion en 5 Septiembre 2014, 08:37 am
Bienvenido al foro.

Te pongo las cosillas que he ido viendo al revisar tu código.

1. Estás usando cabeceras de C y de C++

Código
  1. #include <iostream>
  2. #include <stdlib.h>

La cabecera 'iostream' es propia de C++, sin embargo 'stdlib.h' es de C. Salvo que no haya alternativas es mejor no mezclar. Esto no es un error en sí, es una recomendación.

Además, no veo motivos para tener el include de 'stdlib.h', ya que no estás accediendo a ninguna función declarada en dicha librería. Tener includes innecesarios incrementa el tiempo de compilación, aunque en este ejemplo no se note.

2. Tener conceptos claros

Código
  1. for(x=0;x<100;x++)  // recorro y lleno el arreglo con los # del 1 al 100
  2.   {
  3.       array_prime[x]=num++;
  4.   }

Sobre las líneas de arriba te puedo decir dos cosas:

* 'num' es una variable que te puedes ahorrar. De hecho 'num=x+1' durante todo el ciclo.
* 'array_prime' también te la puedes ahorrar. Si te das cuenta, en la línea 25 ocurre que 'array_prime[ x ]==x+1', luego puedes hacer la sustitución y ahorrarte tanto el arreglo como el bucle que tienes destacado en este apartado.

3. Tienes que aprender a depurar el código.

Código
  1. for(x=0;x<100;x++) //Recorro el arreglo
  2.     {
  3.       for(z=1;z<=x;z++) // for para probar cada numero del arreglo es primo
  4.       {
  5.         if(x%z==0)add++;  // si el residuo es 0, contador add cuenta.
  6.       }
  7.       if(add==2)  // si el contador es igual a 2, el #del arreglo es primo.
  8.       {
  9.          cout<<array_prime[x]; //asigno el #primo al array. imprimo
  10.       }
  11.     }

El error en sí se encuentra en estas líneas... para cada número usas 'add' para contar sus divisores... pero no reinicias el valor de 'add' en ningún momento. Luego su valor no hará sino crecer de forma constante:

* x = 0 -> add = 0
* x = 1 - divisores: 1 -> add = 0 + 1 = 1
* x = 2 - divisores: 1, 2 -> add = 1 + 2 = 3
* x = 3 - divisores: 1, 3 -> add = 3 + 2 = 5
* x = 4 - divisores: 1, 2, 4 -> add = 5 + 3 = 8
* x = 5 - divisores: 1, 5 -> add = 8 + 2 = 10
...

Además, fíjate que no estás comparando los mismos números:

Código
  1. for(x=0;x<100;x++)
  2.     {
  3.       for(z=1;z<=x;z++)
  4.       {
  5.         if(x%z==0)add++;  // AQUI estas mirando si 'x' es primo
  6.       }
  7.       if(add==2)
  8.       {
  9.          cout<<array_prime[x]; // si 'x' es primo, imprimes 'array_prime[x]', que es 'x+1'
  10.       }
  11.     }

Son errores tontos, pero sabiendo usar un depurador los encuentras con cierta facilidad.

A continuación te pongo tu código con algún retoque. He intentado mantener el código original. Como ves te estabas complicando en exceso.

Código
  1. /* Escribir un programa que almacene en un arreglo los
  2.    números primos comprendidos entre 1 y 100. */
  3.  
  4. #include <iostream>
  5. using namespace std;
  6.  
  7. int main()
  8. {
  9.   for( int x=2; x<100; x++ ) //Recorro el arreglo
  10.   {
  11.     int add = 0;
  12.  
  13.     for( int z=1; z<=x; z++ ) // for para probar cada numero del arreglo es primo
  14.     {
  15.       if(x%z==0)add++;  // si el residuo es 0, contador add cuenta.
  16.     }
  17.  
  18.     if(add==2)  // si el contador es igual a 2, el #del arreglo es primo.
  19.     {
  20.        cout << x << " "; //asigno el #primo al array. imprimo
  21.     }
  22.   }
  23.    cin.get();cin.get();
  24.    return 0;
  25. }

Aún así has de saber que tu código está trabajando más de lo necesario para encontrar primos. En el mismo momento en el que encuentras un divisor, el número ya no es primo, por lo que no hace falta que sigas comprobando más combinaciones; además, para saber si un número es primo no hace falta comprobar todo el rango [2, x-1], con comprobar el rango [2, x/2] te sobra. Este rango se podría reducir aún más, pero habría que hacer algún cambio más en el código.

Después de estas pequeñas optimizaciones el código podría lucir tal que:

Código
  1. /* Escribir un programa que almacene en un arreglo los
  2.    números primos comprendidos entre 1 y 100. */
  3.  
  4. #include <iostream>
  5. using namespace std;
  6.  
  7. int main()
  8. {
  9.   for( int x=2; x<100; x++ ) //Recorro el arreglo
  10.   {
  11.     bool primo = true;
  12.  
  13.     int max = x/2;
  14.     for( int z=2; z<=max; z++ )
  15.     {
  16.       if(x%z==0) // Si es divisor, no es primo.
  17.       {
  18.         primo = false;
  19.         break;
  20.       }
  21.     }
  22.  
  23.     if(primo) // Si es primo, lo saco por pantalla.
  24.     {
  25.        cout << x << " ";
  26.     }
  27.   }
  28.    cin.get();cin.get();
  29.    return 0;
  30. }


Título: Re: Array con numeros primos.
Publicado por: Ja_90 en 5 Septiembre 2014, 17:16 pm
Muchas gracias, ya estuve mirando e hice lo que me dijiste del depurador, vi el error al instante. tendré en cuenta todas las recomendaciones, y gracias nuevamente.