我正在研究一个简单的Eratosthenes Sieve算法,代码如下:
int main()
{
const int n = 1000000;
int sqrn = floor(sqrt(n));
bool primes[n + 1] = { 0 }; // false means prime, true not prime
primes[0] = true;
primes[1] = true;
for (int i = 2; i <= sqrn; i++){
if (primes[i] == false) {
int j = i + i;
while (j<=n-1){
primes[j] = true;
j = j + i;
}
}
}
}
我的主要问题是,如果我尝试将搜索数组设置为大于n = 1000000,则此代码会导致堆栈溢出错误。我不确定这是因为编程错误还是因为程序无法容纳大于10 ^ 6个条目的布尔数组?任何建议都表示赞赏。
我遇到的另一个小问题是,在for-loop语句之外设置n的平方根的评估是否提高了执行速度。
谢谢
答案 0 :(得分:2)
您正在堆栈上分配primes
数组。堆栈只有有限的尺寸(它非常大,但它仍然有限)。你可以:
new
答案 1 :(得分:1)
堆栈溢出可能是因为您的堆栈大小不超过1MB(或1MB,具体取决于您的定义)。 bool
通常是1个字节。尝试在堆上分配primes数组(使用new[]
)以避免堆栈大小限制。请记住使用delete[]
释放数组。
此算法的n
的素数也是不正确的。您想将j<=n-1
更改为j<=n
。
答案 2 :(得分:1)
而不是bool primes[n + 1] = { 0 };
,请执行:
std::vector<bool> primes(n+1);
这为足够的素数分配非堆栈空间,并将它们全部初始化为false
。
这个版本的另一个优点是编译器可能专门使用每个值一位,而你的版本每个值使用一个字节。
可能具有更好性能的类似替代方案(但只有在编译时知道大小时才可能)
std::bitset<n+1> primes;
如果您查看其文档,您可以提高代码的性能。