En promedio, la densidad de los números primos cerca de N es aproximadamente 1 / log (N). Dado que log (10 ^ 9) ~ 20, el quinto primo mayor que 10 ^ 9 (es decir, el quinto primo de 10 dígitos) es probablemente alrededor de 10 ^ 9 + 100. Cada número compuesto menor o igual a M tiene un divisor mayor que 1 y menos que la raíz cuadrada de M. La raíz cuadrada de 10 ^ 9 + 100 es aproximadamente 31622.8. De todos modos, el quinto primo de 10 dígitos es extremadamente improbable que sea mayor que 31623 ^ 2 = 10 ^ 9 + 14129.
Entonces, un algoritmo eficiente es generar primero todos los primos menores o iguales a 31622. Esto se puede hacer usando el Tamiz de Eratóstenes. Es más fácil simplemente proporcionar código real (C ++) porque no he escrito pseudocódigo en mucho tiempo:
#include
#include
const int MAX = 31622;
bool is_prime[MAX+1];
std::vector primes;
void sieve() {
memset(is_prime, 1, sizeof is_prime);
is_prime[0] = is_prime[1] = false;
for (int i = 2; i <= MAX; i++)
if (is_prime[i]) {
primes.push_back(i);
for (int j = 2*i; j <= MAX; j += i)
is_prime[j] = false;
}
}
- Cómo convertir 25 cm a mm sin usar una regla
- ¿La falta de competencia matemática interrumpiría mi facilidad de aprendizaje de programación?
- ¿Por qué escribimos A = IA para operaciones de fila y A = AI para operación de columna para encontrar el inverso de una matriz?
- ¿Cuáles son los mejores libros de matemáticas gratuitos para graduados de CS?
- ¿Cómo puedo ordenar rápidamente una matriz de elementos que ya está ordenada, excepto por un pequeño número de elementos, por ejemplo, hasta 1/4 del total, cuyas posiciones se conocen, por ejemplo, 1,2,3,4,8,6 , 7,8,2,10,11,3,13,14,15,16. Este conjunto se ordena guardar 4,8,11?
Como solo esperamos probar unos 100 números, si procede por división de prueba, lo siguiente debería ejecutarse en menos de un segundo:
int i = 1000000000;
int cnt = 0;
while (cnt < 5) {
assert(MAX*MAX <= i);
bool ok = true;
for (int j = 0; j < primes.size(); j++)
if (i % primes[j] == 0) {
ok = false; break;
}
if (ok) {
cnt++;
printf("%d is prime\n", i);
}
i++;
}
De hecho, en mi sistema lleva menos de un milisegundo de tiempo de CPU:
[correo electrónico protegido] : ~ / random_code / so $ g ++ -O3 prime.cpp && time ./a.out
1000000007 es primo
1000000009 es primo
1000000021 es primo
1000000033 es primo
1000000087 es primo
0m0.002s reales
usuario 0m0.000s
sys 0m0.000s