我正在编写一个程序来估计作为素数的非负整数的百分比。以下代码以某种方式产生无限循环,因为我的输出在我正在使用的在线编译器上说“超时”。但是,我无法弄清楚代码的哪一部分产生了这个问题。它看起来非常简单。
#include <iostream>
bool isPrime(unsigned long L) {
if (L < 3) {
return true;
} else {
unsigned long i = 2;
while (i < L)
if (L % i++ == 0)
return false;
}
return true;
}
int main() {
unsigned long k = 0;
unsigned long N = ~k;
unsigned long count = 0;
while (k++ < N)
if (isPrime(k))
++count;
long double percentPrime = count / N;
std::cout << "Percentage of prime numbers from 0 to " << N << " = " << percentPrime;
return 0;
}
答案 0 :(得分:2)
首先,你的循环不是无限的。它将一直运行到0xFFFFFFFF
,这将永远。
它将永远使用的部分原因是您使用的是O(N^2)
算法(因此需要0xFFFFFFFF * 0xFFFFFFFF
次操作才能完成)。
您应该使用筛子,或者至少优化您的is_prime
功能:
bool is_prime(unsigned int i, const std::deque<unsigned int>& previous_primes)
{
std::size_t j = 0;
while (previous_primes[j] * previous_primes[j] <= i)
{
if (i % previous_primes[j] == 0)
return false;
++j;
}
return true;
}
然后你的主要代码就是:
// initialize some known primes
std::deque<unsigned int> primes;
primes.push_back(2);
primes.push_back(3);
primes.push_back(5);
primes.push_back(7);
for (unsigned int i = 9; i <= 0xFFFFFFFF; i += 2)
{
if (is_prime(i, primes))
{
primes.push_back(i);
}
}
// your percentage of primes would be (mathematically) primes.size() / 0xFFFFFFFF
请注意,由于迭代,这将仍然永远循环遍历从9到0xFFFFFFFF的所有奇数整数。
旁注
实际上,您正在编写一个程序来显示以下简单的证据:
随着素数越来越大,最大百分比变为1/some infinite prime
〜= 0.(当{接近无穷大时,f(x) = 1/x
的极限为0)。
所以在这里,数学证明要比你对程序化证明的尝试快得多。
答案 1 :(得分:1)
unsigned long k = 0;
unsigned long N = ~k;
这里N将是0xFFFFFFFF
,这是一个非常大的数字,所以循环不是无限长而是长。
答案 2 :(得分:1)
不是无限的,只是非常长。
如果你写了while (k++ <= N)
而不是while (k++ < N)
...
BTW,1通常不被认为是素数,但是你的代码产生了它。
PS:如果你想粗略估计1...N
范围内素数的百分比,那么你可以简单地做以下数学运算:100/log(N)
,其中log(N)
是自然的N
的对数。
答案 3 :(得分:1)
它似乎并不是无限的,但由于它很长且耗时,因此超时。
我建议用一些技巧改进你的素性测试:
1 - 您只需要测试数字直到其平方根(sqrt(L))
2 - 你只需要测试奇数的素数(所以你可以开始尝试将数字除以3并将测试增加2,所以你将测试3,5,7,9等等。 。)
干杯