我用C++編寫了Eratosthenes篩的這個實現,但是隻要代碼達到59(第16個素數),就停止工作。它只能在舊機器上達到37。當我調試程序時,所有變量似乎都工作正常;該程序只是崩潰。這裏是:(我知道它有很多評論,很多是不必要的。)Eratosthenes篩C++執行錯誤
// 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;
}
我在想這可能是一個溢出問題?
這裏有一個更新的代碼片段,其中只有改變:
const int sieve_size = 500000;
long long *primes = new long long [solution_number];
調試雖然返回一個(喘氣)堆溢出,但在運行編譯版本沒有。編譯後的版本停在104759,重新翻一次。這可能很容易修復。但該程序不打印最後一位,它給你的解決方案。奇怪的。
只是說明:這不是Eratosthenes篩。你正在檢查每一個數字從p²開始爲p:if(j%current_sieve == 0)sieve [j] = 1;',這是審判分裂。 – 2012-03-27 03:33:36
@DanielFischer噢。有效。 :P你可以用其他方式檢查C++的可分性嗎?我知道有像9或11這樣的數字的可分性技巧,但對於更大的素數...... – 2012-03-27 03:47:11
當然,它的工作原理,它只是慢。 Eratosthenes的篩選技巧是根本不檢查可分性。你交叉的'p'的倍數,所以當你在篩子中找到一個素數'p'時,通過用'p'遞增索引來交叉倍數'for(mult = p * p; mult <= limit ; mult + = p)'。我闡述了不同程度[這裏](http://stackoverflow.com/a/8335325/1011995),[這裏](http://stackoverflow.com/a/8643410/1011995),如果你喜歡長時間閱讀,[這裏](http://stackoverflow.com/a/9704912/1011995)。 – 2012-03-27 10:38:37