【发布时间】:2012-03-27 03:14:41
【问题描述】:
我用 C++ 编写了这个埃拉托色尼筛法的实现,但只要代码达到 59(第 16 个素数),它就会停止工作。在我的旧机器上只能达到 37。当我调试程序时,所有变量似乎都工作正常;该程序只是崩溃。这里是:(我知道它有很多 cmets,而且很多是不必要的。)
// Problem 7:What is the 10 001st prime number?
/*This program generates a list of prime numbers and uses the Sieve of Eratosthenes to find them.
*This is done by crossing out multiples of the first known prime (2), taking the first number
*not yet crossed out, and setting that as the next prime to "sieve" with.
*/
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int placeholder; //added at the end to prevent window from closing
const int sieve_size = 10000; //amount of #s to sieve through
const int solution_number = 10001; //# of primes to generate
long long solution; //the 10 001st prime #
long long current_sieve; //current # sieving with
int number_of_primes = 1; //we know the first prime -- 2
long long *primes = new long long [number_of_primes];
primes[0] = 2; //2 is the first prime
bool flag_havePrime = 0; //whether we have our next prime yet; used when saving a prime
bool sieve[sieve_size] = {0}; //0 is "could-be-prime" (not composite), 1 is composite.
sieve[0] = 1; //0 and 1 are not prime #s
sieve[1] = 1;
for (int i = 0; number_of_primes <= solution_number; i++) //each loop sieves with a different prime
{
current_sieve = primes[i];
//This next loop sieves through the array starting with the square of the number we will sieve with,
//this optimizes the run time of the program.
for (long long j=current_sieve*current_sieve; j <= sieve_size; j++)
if (j%current_sieve == 0) sieve[j] = 1;
/*This loop gets our next prime by looking through the array until
*it encounters a number not crossed out yet. If it encounters a prime,
*it increments the number of primes, then saves the new prime into
*primes[]. It also prints that prime (for debugging purposes).
*The "for" loop ends when it finds a prime, which it knows by encountering
*the "havePrime" flag. This needs to be reset before every run.
*/
for (long long j = primes[number_of_primes-1]+1; flag_havePrime == 0; j++)
{
if (sieve[j] == 0)
{
number_of_primes++;
primes[number_of_primes-1] = j; //because array counting starts @ 0
cout << primes[number_of_primes-1] << endl; //because array counting starts @ 0
flag_havePrime = 1;
}
}
flag_havePrime = 0; //resetting this flag
}
solution = primes[number_of_primes-1]; //because array counting starts @ 0
delete[] primes;
primes = 0;
cout << "The 10 001st prime number is:\n";
cout << solution << endl;
cin >> placeholder;
return 0;
}
我认为这可能是溢出问题?
这是一个更新的 sn-p,仅包含更改:
const int sieve_size = 500000;
long long *primes = new long long [solution_number];
虽然调试会返回(喘气)堆溢出,但运行编译版本不会。编译后的版本停止在 104759,超过 1。这可能很容易修复。但是该程序不会打印最后一位,它会为您提供解决方案。很奇怪。
【问题讨论】:
-
请注意:这不是埃拉托色尼筛。您正在检查从 p² 开始的每个数字是否可以被 p 整除:
if (j%current_sieve == 0) sieve[j] = 1;,这是试除法。 -
@DanielFischer 哦,好吧。有效。 :P 你能以其他方式检查 C++ 中的可分性吗?我知道像 9 或 11 这样的数字有除法技巧,但对于更大的素数......