Ver Mensaje Individual
  #6 (permalink)  
Antiguo 03/07/2014, 23:54
Avatar de leosansan
leosansan
 
Fecha de Ingreso: mayo-2012
Ubicación: GRAN CANARIA
Mensajes: 194
Antigüedad: 12 años, 5 meses
Puntos: 49
Respuesta: Buscando números primos, con la criba de Eratóstenes

Cita:
Iniciado por CalgaryCorpus Ver Mensaje
...............................
Este par de multiplicaciones se puede reemplazar por 1 suma, debido a que el ciclo lo que hace es calcular los factores del numero i, es decir calcula 2*i, 3*i, 4*i, ... ( y asi sucesivamente ) y ese valor utiliza.

En vez de multiplicar todas las veces, se puede guardar el valor anterior y descubrir el siguiente sólo sumando i, asi (ver variable "multiplo"):
...............................
Bien observado lo de la multiplicaciónCalgaryCorpus, ya lo he puesto en práctica.

Y lo de inicializar fue un fallo de pasar un código previo, pero también bien observado.

Lo dejo con calloc para además de declarar, inicializar y con N de 10^8 con lo que tarda unos 7 segundos en mostrar el total de primos. Desactivo los printf para que "no pierda tiempo" en calcular el total de primos hasta N:

Código C++:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define N 100000000 /* hasta aqui calculamos los primos */
  4.  
  5. int main() {
  6.   int i, j, z, x = 0;
  7.   int  *nums = calloc( N+1, sizeof ( int ));
  8.   int *prims = calloc( N+1, sizeof ( int ));
  9.   ///puts("\n\tSon PRIMOS:\n");
  10.   ///printf( "\t%4d:::%5d\n", x, 2 );
  11.   prims[x] = 2;
  12.   x++;
  13.   for( i = 3; i <= N; i += 2 )
  14.     if( nums[i] == 0 ) {
  15.       prims[x] = i;
  16.       ///printf( "\t%4d:::%5d\n", x, i );
  17.       x++;
  18.       for( j = ( i <= N ); ( z = ( i * j ) )  <= N; j+=2)
  19.         nums[z] = 1;
  20.     }
  21.   /*for( i = 0; i < x; i ++ )
  22.     printf( "%4d", prims[i] );*/
  23.   printf( "\n  Hasta %d hay %d numeros primos\n\n", N, x );
  24.   free ( nums );
  25.   free ( prims );
  26.   return 0;
  27. }
  28. }


EDITADO:

Mirándolo bien amigo CalgaryCorpus acabo de darme cuenta de un par de detalles. En tu for vas de multiplo = i+i con incrementos de multiplo += i.

Como ejemplo, supongamos para i los valores de 3 y de 5. Aplicándoles el for los valores que tomarían serían de:

3+3=6______5+5=10
+3=9-_____+5=15
+3=12_____+5=20
+3=15_____+5=25
+3=18_____+5=30
.....................

donde se observa que toman de forma inútil valores pares, que de antemano sabemos que no son primos y arrancan siempre con valor par al ser i+i. La forma de evitarlo sería con un paso de 2*i y un valor inicial de 3*i .

Y como ves tu intento de mejora para evitar la multiplicación de i * j se traduce en la introducción de nuevas multiplicaciones. Claro que al ser una de ellas de multiplicar por dos se podría optimizar más fácilmente.

En cualquier caso es de agradecer y motiva que haya gente por ahí que se moleste en mirar con tanto detenimiento los códigos. Gracias por la atención que le has prestado.

Un fuerte saludo.


Última edición por leosansan; 04/07/2014 a las 11:37